专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Java动态代理模式详解

Java动态代理模式详解

更新时间:2022-08-09 10:04:04 来源:动力节点 浏览1532次

什么是动态代理:

代理类在程序运行时创建代理的方式叫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设计模式,里面有更丰富的知识等着大家去学习,希望对大家能够有所帮助。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>