zoukankan      html  css  js  c++  java
  • java动态代理

    一、使用jdk自带的动态代理机制:

    • 定义一个普通的接口及实现类;
    • 定义一个InvocationHandler的实现类用于织入横向插入的操作(此处为打印信息);
    • 生成接口的代理类;
    • 调用接口方法,实现动态代理。
    • package aopdemo.jdk;
      
      public interface INormalService {
      
          public void service();
      
      }
      package aopdemo.jdk;
      
      public class NormalServiceImpl implements INormalService {
      
          @Override
          public void service() {
              System.out.println("invoke service");
      
          }
      
      }
      package aopdemo.jdk;
      
      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      
      public class MyInvocationHandler implements InvocationHandler {
      
          Object target;
      
          public MyInvocationHandler(Object target) {
              this.target = target;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args)
                  throws Throwable {
              System.out.println("before service");
              Object object = method.invoke(target, args);
              System.out.println("after service");
              return object;
          }
      
      }
      package aopdemo.jdk;
      
      import java.lang.reflect.Proxy;
      
      public class JdkProxyDemo {
      
          public static void main(String[] args) {
      
              INormalService normalService = new NormalServiceImpl();
              MyInvocationHandler handler = new MyInvocationHandler(normalService);
              INormalService iNormalService = (INormalService) Proxy
                      .newProxyInstance(normalService.getClass().getClassLoader(),
                              normalService.getClass().getInterfaces(), handler);
              iNormalService.service();
      
          }
      
      }

      执行结果为:

             before service
             invoke service
             after service

    二、使用Cglib实现动态代理

    • 定义一个普通的类;
    • 定义一个MethodInterceptor的实现类用于织入横向插入的操作(此处为打印信息);
    • 使用enhancer增强器生成普通类的代理类;
    • 调用代理类的方法,实现动态代理。
    package aopdemo.cglib;
    
    public class NormalServiceImpl {
    
        public void service() {
            System.out.println("invoke service");
        }
    
    }
    package aopdemo.cglib;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    public class CglibProxy implements MethodInterceptor {
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args,
                MethodProxy proxy) throws Throwable {
            System.out.println("before service");
            Object object = proxy.invokeSuper(obj, args);
            System.out.println("after service");
            return object;
        }
    
    }
    package aopdemo.cglib;
    
    import net.sf.cglib.proxy.Enhancer;
    
    public class CglibDemo {
    
        public static void main(String[] args) {
    
            CglibProxy cglibProxy = new CglibProxy();
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(NormalServiceImpl.class);
            enhancer.setCallback(cglibProxy);
            NormalServiceImpl normalServiceImpl = (NormalServiceImpl) enhancer
                    .create();
            normalServiceImpl.service();
        }
    
    }

    最后输出:

    before service
    invoke service
    after service

    三、总结

    jdk代理只能动态代理接口;

    Cglib代理可以代理普通的类。

    四、spring如何配置代理方式?

    <aop:aspectj-autoproxy proxy-target-class="true" />

    若配为true表示强制使用Cglib来代理;

    若不配为true:

    如果要被代理的对象是个实现类,那么Spring会使用JDK动态代理来完成操作(Spirng默认采用JDK动态代理实现机制);

    如果要被代理的对象不是个实现类,Spring会强制使用Cglib来实现动态代理。

  • 相关阅读:
    LeetCode 121. Best Time to Buy and Sell Stock
    LeetCode 221. Maximal Square
    LeetCode 152. Maximum Product Subarray
    LeetCode 53. Maximum Subarray
    LeetCode 91. Decode Ways
    LeetCode 64. Minimum Path Sum
    LeetCode 264. Ugly Number II
    LeetCode 263. Ugly Number
    LeetCode 50. Pow(x, n)
    LeetCode 279. Perfect Squares
  • 原文地址:https://www.cnblogs.com/silenceshining/p/11129688.html
Copyright © 2011-2022 走看看