• 代理模式,CGLIB 与Spring AOP实现原理


    参考资料:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html

    AOP 面向接口的编程,JAVA的另一个特性。

    其实现原理主要是使用代理模式。


     代理模式,就是利用一个对象的代理去执行目标对象的方法,同时可以在执行目标对象方法前后执行其他语句。

    代理模式的对象必须实现接口。

    目标对象实现的接口

    package com.jason.prj;
    
    /**
     * Created by Administrator on 2016/6/19.
     */
    public interface BookFacade {
        public void addBook();
        public void deleteBook();
    }

    目标对象

    package com.jason.prj;
    
    /**
     * Created by Administrator on 2016/6/19.
     */
    public class BookFacadeImpl implements BookFacade {
        @Override
        public void addBook() {
            System.out.println("Add Book Logic is running ...");
        }
    
        @Override
        public void deleteBook() {
            System.out.println("Delete Book Logic is running ...");
        }
    }

     实现InvocationHandler接口

    package com.jason.prj;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * Created by Administrator on 2016/6/19.
     */
    public class BookFacadeProxy implements InvocationHandler{
        private Object target;
    
        public Object bind(Object target){
            this.target = target;
            //生成代理对象
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = null;
            System.out.println("Proxy start ...");
            System.out.println("Class Name: "+target.getClass().getName());
            System.out.println("Method Name: "+method.getName());
            //执行目标方法
            result = method.invoke(target, args);
            System.out.println("Proxy end ...");
            return null;
        }
    }

    测试

    package com.jason.prj;
    
    import static org.junit.Assert.*;
    
    public class BookFacadeProxyTest {
    
        @org.junit.Test
        public void testBind() throws Exception {
            BookFacadeProxy proxy = new BookFacadeProxy();
            //生成代理
            BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());
            //利用代理执行方法
            bookProxy.addBook();
            //利用代理执行方法
            bookProxy.deleteBook();
        }
    }

    测试结果

    Proxy start ... 
    Class Name: com.jason.prj.BookFacadeImpl
    Method Name: addBook
    Add Book Logic is running ... //执行目标方法 addBook()
    Proxy end ...
    Proxy start ...
    Class Name: com.jason.prj.BookFacadeImpl
    Method Name: deleteBook
    Delete Book Logic is running ... //执行目标方法 deleteBook()
    Proxy end ...

    用CGLIB实现代理

    JAVA自身的代理需要目标对象实现接口,使用CGLIB就不需要实现接口。

     首先来创建一个不实现接口的类

     1 package com.jason.prj;
     2 
     3 /**
     4  * Created by Administrator on 2016/6/20.
     5  */
     6 public class BookFacadeImp1 {
     7     public void addBook(){
     8         System.out.println("Add book ...");
     9     }
    10     public void deleteBook(){
    11         System.out.println("Delete book ...");
    12     }
    13 }

    实现MethodInterceptor接口

     1 package com.jason.prj;
     2 
     3 import net.sf.cglib.proxy.Enhancer;
     4 import net.sf.cglib.proxy.MethodInterceptor;
     5 import net.sf.cglib.proxy.MethodProxy;
     6 
     7 import java.lang.reflect.Method;
     8 
     9 /**
    10  * Created by Administrator on 2016/6/20.
    11  */
    12 public class BookFacadeCglib implements MethodInterceptor {
    13     private Object target;
    14 
    15     public Object getInstance(Object target){
    16         this.target = target;
    17         Enhancer enhancer = new Enhancer();
    18         enhancer.setSuperclass(this.target.getClass());
    19         enhancer.setCallback(this);
    20         return enhancer.create();
    21     }
    22 
    23     @Override
    24     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    25         System.out.println("Transaction Starts");
    26         methodProxy.invokeSuper(o, objects);
    27         System.out.println("Transaction Ends");
    28         return null;
    29     }
    30 }

    测试代码

     1 package com.jason.prj;
     2 
     3 /**
     4  * Created by Administrator on 2016/6/20.
     5  */
     6 public class Testlib {
     7     public static void main(String[] args){
     8         BookFacadeCglib cglib = new BookFacadeCglib();
     9         BookFacadeImp1 bookCglib = (BookFacadeImp1) cglib.getInstance(new BookFacadeImp1());
    10         bookCglib.addBook();
    11     }
    12 }

    测试结果

    Transaction Starts
    Add book ...
    Transaction Ends

    代理模式为Spring AOP的实现原理

    可以利用代理模式在执行目标方法前后去加入通知,完成对业务功能的分割,形成切面。

  • 相关阅读:
    C语言实现大数计算
    shell编程题(九)
    shell编程题(八)
    信号(一)
    shell编程题(六)
    C语言实现webServer
    chrome导入导出常用书签
    JdbcTemplate
    数据库连接池
    JDBC
  • 原文地址:https://www.cnblogs.com/xdlaoliu/p/5599090.html
Copyright © 2020-2023  润新知