JAVA中的两种动态代理

什么叫代理:通过代理对象来访问真实对象的方法。代理商代理厂家产品。

完成代理,需要两步骤:

  1. 建立代理对象与真实对象的代理关系,返回代理对象,代理对象类型是真实对象类型。
  2. 实现代理对象调用真实对象方法的代理逻辑:在调用真实方法前,或后,或异常情况下的一些处理

代理技术有两种

  1. JDK动态代理:InvocationHandler
  2. CGLIB动态代理:第三方包,MethodInterceptor

应用场景:

  1. 事务管理
  2. Controller通知,控制器通知
  3. Spring 缓存管理器

JDK动态代理

实现InvocationHandler,

  1. 建立代理对象与真实对象的代理关系,返回代理对象:代理对象可以访问真实对象接口下的所有方法,如果真实对象没有实现接口,不能被jdk代理
  2. 实现代理逻辑
  3. public class JdkProxyTest implements InvocationHandler {

       
    private Object realObject;

       
    /**
         *
    建立代理对象与真实对象的对应关系
         * @param targetObject 真实对象,要求必须有实现的接口
         * @return 代理对象,类型与真实对象一致
         */
       
    public Object getProxy(Object targetObject) {
           
    this.realObject = targetObject;
            return
    Proxy.newProxyInstance(
                        targetObject.getClass().getClassLoader()
    ,
                       
    targetObject.getClass().getInterfaces(),
                        this  
    //当前对象实例作为代理对象
                    );
       
    }

       
    @Override
       
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
           
    //spring事务管理,执行SQL前先获取数据库连接
            System.out.println("在目标方法执行前执行的逻辑");
           
    Object value = null;
            try
    {
             //在执行目标函数之前,通过责任链模式,执行拦截器,当所有的拦截器都执行通过时,才能执行目标函数,

// handlerAdapter里,就是先执行拦截器,在执行控制器方法的,封装成了HandlerExecutionChain

            //执行业务逻辑

            value = method.invoke(realObject,args);

        } catch (Exception e) {

            e.printStackTrace();

            //当目标方法执行出现异常时,spring事务管理回滚事务.

            System.out.println("在目标方法执行出现异常时执行的逻辑");

        }

        //spring事务管理,在执行完目标方法时,释放数据库连接

        System.out.println("在目标方法执行后执行的逻辑");

        return value;

    }

}

CGLIB动态代理

第三方包,实现MethodInterceptor接口

  1. 建立代理对象与真实对象的对应关系:真实对象可以没有实现接口,代理对象类型是真实对象类型
  2. 实现代理逻辑:
  3. pubic class CgibProxyTest impements MethodInterceptor {     /**      * 创建代理对象与真实对象的对应关系      * @param cz 真实对象      * @return 返回代理对象      */     pubic Object getProxy(Cass clz) {         //增强类         Enhancer enhancer = new Enhancer();         //设置真实对象         enhancer.setSupercass(clz);         //设置当前实例对象为代理对象         enhancer.setCalback(this);         return  enhancer.create();     }     @Override     pubic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwabe {         //spring事务管理,执行SQL前先获取数据库连接         System.out.printn("在目标方法执行前执行的逻辑");         Object resut = nul;         try {
            //在执行目标函数之前,通过责任链模式,执行拦截器,当所有的拦截器都执行通过时,才能执行目标函数,

// handlerAdapter里,就是先执行拦截器,在执行控制器方法的,封装成了HandlerExecutionChain

            //执行业务逻辑

            result = methodProxy.invokeSuper(proxy,args);

        } catch (Exception e) {

            e.printStackTrace();

            //当目标方法执行出现异常时,spring事务管理回滚事务.

            System.out.println("在目标方法执行出现异常时执行的逻辑");

        }

        //spring事务管理,在执行完目标方法时,释放数据库连接

        System.out.println("在目标方法执行后执行的逻辑");

        return result;

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值