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

     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的输出语句结果在运行结果之前显示出来

  • 相关阅读:
    类成员之静态字段和普通字段、静态方法和普通方法
    类的导出
    面向对象之继承
    面向对象之封装
    面向对象与函数式的对比
    计算器
    模拟信用卡登录程序
    /etc/fstab
    解决 Your project contains error(s),please fix them before running your applica ..
    C#之SqlDependency数据库缓存
  • 原文地址:https://www.cnblogs.com/1234AAA/p/8529972.html
Copyright © 2011-2022 走看看