zoukankan      html  css  js  c++  java
  • Spring核心技术AOP实现原理

    关于Spring的AOP也是Spring的非常重要的一项技术。大致上可以这样说,面向切面编程,它的出现说明可以在不修改代码的情况下实现对功能的增强。而增强就是给一个方法增加一些功能。AOP主要思想就是把增强的代码可以单独写成一个方法。比如说想对某个方法增加一个检测权限的功能,就可以单独写成一个checkPrivilege方法。可以在需要被增强的方法执行之前,自动的让checkPriviliege方法执行,就像在这个方法前形成一个切面,在切面出安装一个checkPriviliege方法。最终在没有修改源代码的情况下实现功能增强了。这就是它的一个思想,其Spring中的AOP实现有两种方式。分别是JDK代理和Cglib代理。先说说JDK代理:它只能对实现接口的类产生代理。

    接口:

    public interface PostCard {
        public void soup();
    }

    类实现以上接口:

    @Service("postCard")
    public class PostCardImpl implements PostCard{
    
        public void soup() {
            System.out.println("我是postcard...");
        }
    
    }

    创建代理类,该类必须要实现InvocationHandler接口,代码如下:

    /*
     * 动态代理实现
     * */
    
    public class JdkProxy implements InvocationHandler{
        
        private PostCard postCard;  //增强的目标
        
        /*
         * 构造方法
         * */
        public JdkProxy(PostCard postCard) {
            super();
            this.postCard = postCard;
        }
    
        
        
        /*
         * 利用JDK代理动态生成对象的方法
         * newProxyInstance的三个参数
         * loader:目标类的加载器
         * interfaces:目标类所实现的接口
         * handler:回调
         * */
        public PostCard create(){
            PostCard proxy = (PostCard) Proxy.newProxyInstance(postCard.getClass().getClassLoader(), postCard.getClass().getInterfaces(), this);
            return proxy;
        }
        
    
        /*
         * 执行目标对象的方法
         * */
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            
            System.out.println("检测功能before");
            
    //        调用目标方法
            Object result = method.invoke(postCard, args);
            
            System.out.println("检测功能after");
            
            return result;
        }
    }

    测试:

        @Test
        public void test() {
            
    //        实例化目标对象
            PostCard cardImpl = new PostCardImpl();
            
    //        实例化代理对象
            JdkProxy proxy = new JdkProxy(cardImpl);
            
    //        生成代理对象
            PostCard create = proxy.create();
        
    //        调用代理对象方法
            create.soup();
        }

     而cglib对象则是对没有实现接口类的增强,JDK代理无法做到这一点。cglib代理就是生成目标类的子类来增强。如下为案例,复用以上的类无须实现接口。然后创建cglib代理类,代码如下:

    //代理类
    public class CglibProxy implements MethodInterceptor{
    
        /*
         * 调用构造函数的时,将类对象创建出来
         * */
        private PostCard postCard;  //增强的目标
    
        public CglibProxy(PostCard postCard){
            this.postCard=postCard;
        }
        
    //    利用cglib生成代理对象
    
        public PostCard create(){
    //        创建cglib的核心对象
            Enhancer enhancer = new Enhancer();
            
    //        设置父类
            enhancer.setSuperclass(postCard.getClass());
            
    //        设置回调
            enhancer.setCallback(this);
            
    //        创建代理对象
            PostCard proxy = (PostCard) enhancer.create();
            
            return proxy;      
        }
      
        /*
         * 调用目标方法时,实质上就是调用该方法
         * 参数1:代理对象
         * 参数2:目标方法
         * 参数3:目标方法的形参
         * 参数4:代理方法
         * */
        public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
            
    //        添加检测权限的方法
            System.out.println("检测权限cglib...");
            
    //        调用目标父类方法
            Object object = arg3.invokeSuper(arg0, arg2);
            
            return object;
        }
    }

    测试代码如下:

        @Test
        public void test1() {
    //        目标
            PostCard impl = new PostCardImpl();
        
    //        实例化代理对象
            CglibProxy cglibProxy = new CglibProxy(impl);
            
    //        生成代理对象
            PostCard create = cglibProxy.create();
            
    //        调用代理对象的方法
            create.soup();
        }

    以上就是这2种代理的区别,SpringAOP编程就是利用的代理方法实现切面编程。

  • 相关阅读:
    linux-溢出程序
    linux下edb调试器
    IOS 学习
    xcode+OC基础学习
    mailcarrier25 EMAIL程序 典型覆盖返回地址XPSP3
    easyftpsvr-1.7.0.2 POC
    VS2010 MSDN Help Library 出现问题处理方法
    虚拟机XP 连接 虚拟机 linux
    修复文章···
    枚举所有进程所有模块,删除制定进程
  • 原文地址:https://www.cnblogs.com/lichangyun/p/9668492.html
Copyright © 2011-2022 走看看