Spring 容器AOP的实现原理——动态代理

参考:http://wiki.jikexueyuan.com/project/ssh-noob-learning/dynamic-proxy.html(from极客学院)

一、介绍

Spring的动态代理有两种:一是JDK的动态代理;另一个是cglib动态代理(通过修改字节码来实现代理)。

今天主要讨论JDK动态代理的方式。

JDK的代理方式主要就是通过反射跟动态编译来实现的,主要搭配InvocationHandler和Proxy来实现,下面的例子中使用了两层代理(即代理上加了一层代理)。

二、实例

1. 公共接口

1 package com.tgb.proxy;
2 
3 public interface UserMgr {
4 
5     void addUser();
6     void delUser();
7     
8 }

 

2. 实现类

 1 package com.tgb.proxy;
 2 
 3 public class UserMgrImpl implements UserMgr {
 4 
 5     @Override
 6     public void addUser() {
 7         System.out.println("添加用户....");
 8     }
 9 
10     @Override
11     public void delUser() {
12         System.out.println("删除用户.....");
13     }
14 
15 }

 

3. TransactionHandler(InvocationHandler的实现)

 1 package com.tgb.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 public class TransactionHandler implements InvocationHandler {
 7 
 8     private Object target;
 9     
10     public TransactionHandler(Object target){
11         super();
12         this.target = target;
13     }
14 
15     @Override
16     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
17         
18         System.out.println("开启事务...");
19         
20         method.invoke(target);
21         
22         System.out.println("提交事务...");
23         
24         return null;
25     }
26     
27 
28 }

 

4. TimeHandler(InvocationHandler的实现)

 1 package com.tgb.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 import java.util.Calendar;
 6 
 7 public class TimeHandler implements InvocationHandler {
 8 
 9     private Object target;
10 
11     public TimeHandler(Object target) {
12         super();
13         this.target = target;
14     }
15 
16     @Override
17     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
18 
19         Calendar calendar = Calendar.getInstance();
20 
21         System.out.println("start time:" + calendar.get(Calendar.HOUR_OF_DAY));
22 
23         method.invoke(target);
24 
25         System.out.println("end time:" + calendar.get(Calendar.HOUR_OF_DAY));
26 
27         return null;
28     }
29 
30 }

 

5. 测试类

 1 package com.tgb.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Proxy;
 5 
 6 public class Client {
 7 
 8     public static void main(String[] args) {
 9 
10         UserMgr userMgr = new UserMgrImpl();
11 
12         // 1.第一层代理----------通过动态代理,添加事务处理
13         InvocationHandler handler = new TransactionHandler(userMgr);
14         UserMgr userMgrProxy = (UserMgr) Proxy.newProxyInstance(userMgr.getClass().getClassLoader(),
15                 userMgr.getClass().getInterfaces(), handler);
16 
17         // 2.第二层代理----------通过动态代理,添加时间处理
18         InvocationHandler handler2 = new TimeHandler(userMgrProxy);
19         UserMgr userMgrProxy2 = (UserMgr) Proxy.newProxyInstance(userMgrProxy.getClass().getClassLoader(),
20                 userMgrProxy.getClass().getInterfaces(), handler2);
21 
22         userMgrProxy2.addUser();
23 
24         System.out.println("========================================");
25 
26         userMgrProxy2.delUser();
27 
28     }
29 }

 

输出结果:

start time:Tue Aug 09 23:54:54 CST 2016
开启事务...
添加用户....
提交事务...
end time:Tue Aug 09 23:54:54 CST 2016
========================================
start time:Tue Aug 09 23:54:54 CST 2016
开启事务...
删除用户.....
提交事务...
end time:Tue Aug 09 23:54:54 CST 2016
(文/Mr.van_Gogh)
本文来源:http://www.cnblogs.com/jiangyi-uestc/p/5755133.html

 


如果给你带来帮助,欢迎微信或支付宝扫一扫,赞一下。