zoukankan      html  css  js  c++  java
  • SpringAOP实现(原理)

    AOP原理:
    AOP分为:JDK动态代理和CGLIB代理
    静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
                 注意: 目标代理类不能是final 字段、方法、类
    动态代理:在程序运行时,运用反射机制动态创建而成。 

    JDK动态代理实现:必须有接口和实现类
    ?疑问:为什么必须是接口和实现类,既然核心是反射,普通的java也是可以通过反射实现注入,为什么必须是接口及实现类

    UserService :
    package com.gillion.aop; 
    /** 

    * @Description 目标接口 
    * @author huyuangui@aliyun.com 
    * @time 2015年1月9日 下午2:28:00 
    * @version 1.0.0 
    */ 
    public interface UserService { 
    /** 
    * 根据ID删除用户 
    * @param id 
    * @return 
    */ 
    public String deleteUser(String id); 
    }

    UserService实现类 :
    package com.gillion.aop.impl; 

    import com.gillion.aop.UserService; 

    /** 
    * @Description UserService实现类 
    * @author huyuangui@aliyun.com 
    * @time 2015年1月9日 下午2:28:31 
    * @version 1.0.0 
    */ 
    public class UserServiceImpl implements UserService { 
    public String deleteUser(String id) { 
    System.out.println("实现类修改ID前"+id); 
    System.out.println("实现类修改ID为1111"); 
    id="1111"; 
    return id; 

    }
    JDK动态代理实现:
    package com.gillion.aop;
     
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
     
    public class JdkAOP implements InvocationHandler {  
       
      // 目标对象  
      private Object target;  
       
      /**
       * 构造方法
       * @param target 目标对象  
       */  
      public JdkAOP(Object target) {  
          super();  
          this.target = target;  
      }  
     
     
      /**
       * 执行目标对象的方法
       */  
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
       System.out.println("------------------before------------------id:"+args[0]);  
       // 在目标对象的方法执行之前简单的打印一下  
          System.out.println("------------------before------------------");  
          System.out.println("修改第一个参数为ddff");
          args[0]="ddff";
          // 执行目标对象的方法  
          Object result = method.invoke(target, args);
          System.out.println("结果返回:"+result);
          System.out.println("修改结果为:ddfdfd");
          result="ddfdfd";
          // 在目标对象的方法执行之后简单的打印一下  
          System.out.println("-------------------after------------------");  
           
          return result;  
      }  
     
      /**
       * 获取目标对象的代理对象
       * @return 代理对象
       */  
      public Object getProxy() {  
          return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),  
                  target.getClass().getInterfaces(), this);  
      }
     
    }  

    测试类:

    package com.gillion.aop;
     
    import com.gillion.aop.impl.UserServiceImpl;
     
    public class TestJdkAOP {
     public static void main(String []ages){
      // 实例化目标对象  
         UserService userService = new UserServiceImpl();  
           
         // 实例化InvocationHandler  
         JdkAOP invocationHandler = new JdkAOP(userService);  
           
         // 根据目标对象生成代理对象  
         UserService proxy = (UserService) invocationHandler.getProxy();  
         String id="333";
         System.out.println("调用前id:"+id);
         // 调用代理对象的方法  
         id=proxy.deleteUser(id);
         System.out.println("调用后id:"+id);
     }
    }

    结果:
    调用前id:333
    ------------------before------------------id:333
    ------------------before------------------
    修改第一个参数为ddff
    实现类修改ID前ddff
    实现类修改ID为1111
    结果返回:1111
    修改结果为:ddfdfd
    -------------------after------------------
    调用后id:ddfdfd

    Cglib动态代理 :
    JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
     
    普通java类:Book

    package com.gillion.aop.cglib; 

    /** 
    * @Description BOOK 普通java 
    * @author huyuangui@aliyun.com 
    * @time 2015年1月9日 下午2:51:40 
    * @version 1.0.0 
    */ 
    public class Book { 
    public String test(String id) 

    System.out.println("Book更改id前id:"+id); 
    id="123456"; 
    System.out.println("Book更改id=123456"); 
    return id; 

    }
    代理类:BookCglib
    package com.gillion.aop.cglib; 

    import java.lang.reflect.Method; 

    import net.sf.cglib.proxy.Enhancer; 
    import net.sf.cglib.proxy.MethodInterceptor; 
    import net.sf.cglib.proxy.MethodProxy; 

    /** 
    * @Description Cglib代理Book(普通java) 
    * @author huyuangui@aliyun.com 
    * @time 2015年1月9日 下午3:17:03 
    * @version 1.0.0 
    */ 
    public class BookCglib implements MethodInterceptor { 
    private Object target; 

    /** 
    * 创建代理对象 

    * @param target 
    * @return 
    */ 
    public Object getInstance(Object target) { 
    this.target = target; 
    Enhancer enhancer = new Enhancer(); 
    enhancer.setSuperclass(this.target.getClass()); 
    // 回调方法 
    enhancer.setCallback(this); 
    // 创建代理对象 
    return enhancer.create(); 


    // 回调方法 
    public Object intercept(Object obj, Method method, Object[] args, 
    MethodProxy proxy) throws Throwable { 
    System.out.println("Cglib事物开始"); 
    System.out.println("Cglib设置第一个参数为1"); 
    if(args!=null) 
    args[0]="1"; 
    Object result=proxy.invokeSuper(obj, args); 
    System.out.println("Cglib调用后---返回结果:"+result); 
    System.out.println("Cglib改变返回结果:654321"); 
    result="654321"; 
    System.out.println("Cglib事物结束"); 
    return result; 




    }   
    测试类:
    package com.gillion.aop.cglib;
     
    public class TestCglib {
     public static void main(String[] args) {  
            BookCglib cglib=new BookCglib();  
            Book bookCglib=(Book)cglib.getInstance(new Book());  
            String id="dd";
            System.out.println("未调用前id:"+id);
            bookCglib.test(id);
        }  
    }

     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    tensorflow 查看模型输入输出saved_model_cli show --dir ./xxxx --all
    tensorflow models api:ValueError: Tensor conversion requested dtype string for Tensor with dtype float32: 'Tensor("arg0:0", shape=(), dtype=float32, device=/device:CPU:0)'
    python,ModuleNotFoundError,is not a package
    在docker集群下,使用VNC,物理机器重启后VNC失败解决
    2、闵氏空间
    1、爱因斯相对论(狭义相对论)
    tensorflow object detection api graph rewriter
    tensorflow_目标识别object_detection_api,RuntimeError: main thread is not in main loop,fig = plt.figure(frameon=False)_tkinter.TclError: no display name and no $DISPLAY environment variable
    目标检测识别在排除标注不标准问题下,为什么得分最高的框,不一定是最准的框.
    JS中各种变量类型在条件判断为false的情况
  • 原文地址:https://www.cnblogs.com/erpzj/p/4220423.html
Copyright © 2011-2022 走看看