首页 > 技术文章 > 代理模式,CGLIB 与Spring AOP实现原理

xdlaoliu 2016-06-19 22:40 原文

参考资料: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的实现原理

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

推荐阅读