参考资料: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的实现原理
可以利用代理模式在执行目标方法前后去加入通知,完成对业务功能的分割,形成切面。