10.AOP原理---java动态代理

java的动态代理:动态生成一个代理类来调用被代理的对象。(个人理解)

动态代理的调用生成的对象是生成的是代理对象(userDaoProxy),而不是被代理的实现类(userDaoImpl)。

动态编译成一个代理对象的字节码,这个对象实现了和被代理类相同的接口。

内部实现原理:

java的proxy会代理出入接口的所有的方法,将接口的方法和参数会传到拦截器中的invoke方法中。

实现步骤:

1.拦截器类intercepter实现InvoctionHandler接口

2.拦截器类重写invoke方法

3.用java的Proxy的静态方法newProxyInstance(classload,interface,intercepter)

具体事例:

动态代理示例: 

 

1 package net.battier.dao;  
2   
3 public interface BookFacade {  
4     public void addBook();  
5 }
接口类
 1 package net.battier.dao.impl;  
 2   
 3 import net.battier.dao.BookFacade;  
 4   
 5 public class BookFacadeImpl implements BookFacade {  
 6   
 7     @Override  
 8     public void addBook() {  
 9         System.out.println("增加图书方法。。。");  
10     }  
11   
12 }  
实现类
 1 BookFacadeProxy.java  
 2   
 3 package net.battier.proxy;  
 4   
 5 import java.lang.reflect.InvocationHandler;  
 6 import java.lang.reflect.Method;  
 7 import java.lang.reflect.Proxy;  
 8   
 9 /** 
10  * JDK动态代理代理类 
11  *  
12  * @author student 
13  *  
14  */  
15 public class BookFacadeProxy implements InvocationHandler {  
16     private Object target;  
17     /** 
18      * 绑定委托对象并返回一个代理类 
19      * @param target 
20      * @return 
21      */  
22     public Object bind(Object target) {  
23         this.target = target;  
24         //取得代理对象  
25         return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
26                 target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)  
27     }  
28   
29     @Override  
30     /** 
31      * 调用方法 
32      */  
33     public Object invoke(Object proxy, Method method, Object[] args)  
34             throws Throwable {  
35         Object result=null;  
36         System.out.println("事物开始");  
37         //执行方法  
38         result=method.invoke(target, args);  
39         System.out.println("事物结束");  
40         return result;  
41     }  
42   
43 }  
jdk动态代理类
 1 package net.battier.test;  
 2   
 3 import net.battier.dao.BookFacade;  
 4 import net.battier.dao.impl.BookFacadeImpl;  
 5 import net.battier.proxy.BookFacadeProxy;  
 6   
 7 public class TestProxy {  
 8   
 9     public static void main(String[] args) {  
10         BookFacadeProxy proxy = new BookFacadeProxy();  
11         BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());  
12         bookProxy.addBook();  
13     }  
14   
15 }  
测试类

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

事例:

1 package net.battier.dao;  
2   
3 public interface BookFacade {  
4     public void addBook();  
5 } 
接口
 1 package net.battier.dao.impl;  
 2   
 3 /** 
 4  * 这个是没有实现接口的实现类 
 5  *  
 6  * @author student 
 7  *  
 8  */  
 9 public class BookFacadeImpl1 {  
10     public void addBook() {  
11         System.out.println("增加图书的普通方法...");  
12     }  
13 } 
实现类
 1 package net.battier.proxy;  
 2   
 3 import java.lang.reflect.Method;  
 4   
 5 import net.sf.cglib.proxy.Enhancer;  
 6 import net.sf.cglib.proxy.MethodInterceptor;  
 7 import net.sf.cglib.proxy.MethodProxy;  
 8   
 9 /** 
10  * 使用cglib动态代理 
11  *  
12  * @author student 
13  *  
14  */  
15 public class BookFacadeCglib implements MethodInterceptor {  
16     private Object target;  
17   
18     /** 
19      * 创建代理对象 
20      *  
21      * @param target 
22      * @return 
23      */  
24     public Object getInstance(Object target) {  
25         this.target = target;  
26         Enhancer enhancer = new Enhancer();  
27         enhancer.setSuperclass(this.target.getClass());  
28         // 回调方法  
29         enhancer.setCallback(this);  
30         // 创建代理对象  
31         return enhancer.create();  
32     }  
33   
34     @Override  
35     // 回调方法  
36     public Object intercept(Object obj, Method method, Object[] args,  
37             MethodProxy proxy) throws Throwable {  
38         System.out.println("事物开始");  
39         proxy.invokeSuper(obj, args);  
40         System.out.println("事物结束");  
41         return null;  
42   
43   
44     }  
45   
46 }  
cglib动态代理类
 1 package net.battier.test;  
 2   
 3 import net.battier.dao.impl.BookFacadeImpl1;  
 4 import net.battier.proxy.BookFacadeCglib;  
 5   
 6 public class TestCglib {  
 7       
 8     public static void main(String[] args) {  
 9         BookFacadeCglib cglib=new BookFacadeCglib();  
10         BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());  
11         bookCglib.addBook();  
12     }  
13 }
测试类

 

 

posted @ 2014-05-31 09:26  脚踏实地  阅读(217)  评论(0)    收藏  举报