Spring_14_CGLIB动态代理

CGLIB(父类)动态代理

 * CGLIB需要导入第三方Jar包,或者Maven依赖。

    <!-- https://mvnrepository.com/artifact/cglib/cglib -->
      <dependency>
          <groupId>cglib</groupId>
          <artifactId>cglib</artifactId>
          <version>3.3.0</version>
      </dependency>


 * 第三方CGLIB 动态代理技术,它不要求目标类(被代理的类)实现接口,但是要求目标类不能是最终类,也就是不能被final所修饰,因为CGLIB是基于目标类生成一个子类,把该子类作为代理类,所以目标类必须是可继承的。


 * 使用 Enhancer.create() 创建代理类对象

 * Enhancer.create(type,new MethodCallback)参数详解

   - type:指定要被代理的目标类的自节目对象,也就是指定目标类的类型; 例如: customer.getClass()。

   - Callback:含义是回调, 该对象是一个空接口,作用是让别的接口继承它,我们提供一个方法,在合适的时候帮我们调用做个方法。我们提供使用它的一个子接口叫做MetgodInterceptor接口,拦截器的意思。

   - MetgodInterceptor接口中有一个方法:  public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)

   - intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy)参数解释

         - 前三个参数和JDK动态代理一样的含义

         - proxy代理类对象的引用,也就是 Enhancer.create()方法的返回值。

         - method:对应的是触发intercept()方法执行的method对象。 例如:代理对象调用了XXX方法,那么该方法就会触发invoke()方法执行,那么此时method对应的就是xxx方法。

         - Object[] args : 代理对象调用方法时,传递的实际参数。

         -  MethodProxy methodProxy: 方法代理对象,一般不做处理。
  • 基于父类的动态代理,实在内存中生成一个代理对象,该代理对象继承了目标对象(被代理对象),所以代理对象实际上是目标对象的子类(子对象),代理对象是可以用目标对象接收的。

    代理类
    
     public class DynamicCglibTest {
           public static void main(String[] args) {
    
               //创建一个目标类对象
               final Customer customer = new Customer();
    
               //使用CGLIB创建代理对象
               Customer deliverClerk= (Customer) Enhancer.create(customer.getClass(), new MethodInterceptor() {
                   public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                       //如果是Order方法就增强
                       if("Order".equals(method.getName())){
                         Object result=method.invoke(customer,args);
                           System.out.println("取餐");
                           System.out.println("配送");
                         return result;
                       }else{
                           //原封不动的调用原来的罗辑,反射调用
                           return method.invoke(customer,args);
                       }
    
                   }
               });
    
               //调用目标类的方法
               String result=deliverClerk.Order("鱼香肉丝");
               System.out.println(result);
               String priceResult=deliverClerk.pay(256.2);
               System.out.println(priceResult);
           }
       }
    
    
    

 Custom对象
        
    public class Customer {
        public String Order(String foodName) {
            return "已经下单点了"+foodName;
        }

        public String pay(double price) {
           return "您消费了"+price+"元";
        }

        public void shout() {

        }
    }
上一篇:CentOS 7 源码编译安装 Mysql 5.7


下一篇:死磕Spring之AOP篇 - 初识JDK、CGLIB两种动态代理