代理类在程序运行时创建代理的方式叫Java动态代理模式,也就是说代理类并不是在java代码中定义的,而是在运行的时候动态生成的
1.代理对象不需要实现接口
2.代理对象的生成使用JDK API在内存中动态构建代理对象(我们需要指定代理的接口object/target object implements Type)
3.动态代理也叫:JDK代理、接口代理
JDK中生成代理对象的API代理类的封装:java.lang.reflect.Proxy JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数。完整的写作是:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
注意这个方法是Proxy类中的静态方法,接收的三个参数依次是:
类加载器加载器: 指定当前目标对象使用类加载器,获取加载器的方法固定
类[] 接口:目标对象实现的接口的类型,使用泛型方法确认类型
调用处理程序 h:事件处理,当目标对象的方法被执行时,会触发事件处理器的方法,将当前执行的目标对象的方法作为参数传入
代码示例:接口类IUserDao.java和接口实现类,目标对象UserDao相同,无需修改。在此基础上添加一个代理工厂类(ProxyFactory.java),在这个地方写代理类,然后测试类(需要使用代理的代码)首先建立目标对象和代理对象的连接,然后替换代理对象中的同名方法
代理工厂类:ProxyFactory.java
/** * 创建动态代理对象 * 动态代理不需要实现接口,但是需要指定接口类型 */
public class ProxyFactory{
//维护一个目标对象
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
//给目标对象生成代理对象
public Object getProxyInstance(){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始事务2");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务2");
return returnValue;
}
}
);
}
}
测试类:App.java
/** * 测试类 */
public class App {
public static void main(String[] args) {
//目标对象
IUserDao target = new UserDao();
//【原始的类型 class cn.itcast.b_dynamic.UserDao】
System.out.println(target.getClass());
//给目标对象,创建代理对象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
//class $Proxy0 内存中动态生成的代理对象
System.out.println(proxy.getClass());
//执行方法 【代理对象】
proxy.save();
}
}
总结:代理对象不需要实现接口,但目标对象必须实现接口,否则无法使用动态代理。如果大家想了解更多相关知识,可以关注一下极悦的Java设计模式,里面有更丰富的知识等着大家去学习,希望对大家能够有所帮助。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习