动态代理

 1.动态代理 AOP底层实现:有接口自动应用的就是JDK动态代理

JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,它有几个要求

* 实现InvocationHandler

* 使用Proxy.newProxyInstance产生代理对象

* 被代理的对象必须要实现接口

使用JDK动态代理,目标类必须实现的某个接口,如果某个类没有实现接口则不能生成代理对象。

CGLib 必须依赖于CGLib的类库,Cglib原理是针对目标类生成一个子类,覆盖其中的所有方法,

所以目标类和方法不能声明为final类型。针对接口编程的环境下推荐使用JDK的代理。从执行效率上看,

Cglib动态代理效率较高。在Hibernate中的拦截器其实现考虑到不需要其他接口的条件Hibernate中的

相关代理采用的是CGLib来执行。 

     1)JDK  在运行时运行时注入

          本质:在内存中构建出接口的实现类

          特点:被代理对象,必须有接口

案例:

public interface ISomeService {
    public void doSome();
}


ClassLoader(类加载器) loader,  
Class<?>[] interfaces,
InvocationHandler h

        Proxy.newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        InvocationHandler调度处理器
        public interface InvocationHandler {


        }

        ------------------------Code--------------
        final IUSerDao dao=new UserDaoImpl();
        import java.lang.reflect.Proxy;
        InvocationHandler ih=new InvocationHandler(){
          public Object invoke(Object proxy,Method method,Object[] args){

              ==================前置===================
             Object result=method.invoke(dao,args);
              ==================后置===================

            return result;
          }
          
        };

        IUSerDao proxy=(IUSerDao)Proxy.newProxyInstance(ClassLoader,Interfaces,InvocationHanlder){

        };
        proxy.add();

   2)Cglib  底层,注入,编译期已经注入了

           本质:在内存中生成被代理类(目标类)的【子类】

           特点:可以在没有接口的情况下代理

           对于不使用接口的业务类,无法使用JDK动态代理,cglib采用非常底层的字节码技术,

   可以为一个类创建子类

案例:

public class SomeserviceImpl {
    public void doSome(){
        System.out.println("===最后====");
    }
}
public class Test {
    /*
    * CGLIB动态代理
    * */
    public static void main(String[] args) {
        final SomeserviceImpl someservice=new SomeserviceImpl();
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(someservice.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("===之前===");
                methodProxy.invoke(someservice,objects);
                return null;
            }
        });
        SomeserviceImpl service=( SomeserviceImpl)enhancer.create();
        service.doSome();
    }
}

运行 结果:  将Test的输出语句结果在运行结果之前显示出来

原文地址:https://www.cnblogs.com/1234AAA/p/8529972.html