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
时间: 2024-12-07 02:41:36

Spring 容器AOP的实现原理——动态代理的相关文章

菜鸟学SSH(十四)——Spring容器AOP的实现原理——动态代理

之前写了一篇关于IOC的博客--<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大特性是IOC和AOP. IOC负责将对象动态的注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果,可谓是招之则来,挥之则去.想想都觉得爽,如果现实生活中也有这本事那就爽歪歪了,至于有多爽,各位自己脑补吧:而AOP呢,它实现的就是容器的另一大好处了,就是可以让容器中的对象都享有容器中的公共服务.那么容器是怎么做到的呢?它怎么就能让在它里面的对象自动拥有它

AOP的实现原理——动态代理

IOC负责将对象动态的 注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果,可谓是招之则来,挥之则去.想想都觉得爽,如果现实生活中也有这本事那就爽 歪歪了,至于有多爽,各位自己脑补吧:而AOP呢,它实现的就是容器的另一大好处了,就是可以让容器中的对象都享有容器中的公共服务.那么容器是怎么做到 的呢?它怎么就能让在它里面的对象自动拥有它提供的公共性服务呢?答案就是我们今天要讨论的内容——动态代理. 动 态代理其实并不是什么新鲜的东西,学过设计模式的人都应该知道代理模式,代理模

细说Spring——AOP详解(动态代理实现AOP)

前言 嗯,我应该是有一段实现没有写过博客了,在写完了细说Spring——AOP详解(AOP概览)之后,我发现我不知道该怎么写AOP这一部分,所以就把写博客这件事给放下了,但是这件事情又不想就这么放弃,所以今天我仔细思考了一下,决定还是要克服困难,我仔细的想了一下怎么讲解AOP实现这一部分,然后我决定由浅入深的讲解动态代理,然后用动态代理实现一个简单的AOP,感觉这样能够让人对AOP的原理有一个比较深刻的认识,希望能帮到大家.而且最近学习又组建了ACM比赛的队伍,虽然已经要大三了,按理来说应该一心

基于spring的aop实现多数据源动态切换

https://lanjingling.github.io/2016/02/15/spring-aop-dynamicdatasource/ 基于spring的aop实现多数据源动态切换 发表于 2016-02-15   |   分类于 spring  | 一.多数据源动态切换原理 项目中我们经常会遇到多数据源的问题,尤其是数据同步或定时任务等项目更是如此:又例如:读写分离数据库配置的系统. 1.多数据源设置: 1)静态数据源切换:一般情况下,我们可以配置多个数据源,然后为每个数据源写一套对应的

Spring学习笔记-AOP前传之动态代理

假设有如下需求: 写一个计算器类,里面包含加减乘除四个方法.在每个方法开始前打印出该方法开始的消息,在每个方法结束前打印出该方法结束的消息和计算的结果. 普通方法,先写一个借口,然后在接口里实现四个方法.在每个方法里加上要打印的语句.实现代码如下. ArithmeticCalculator接口 package com.spring.aop.helloworld; public interface ArithmeticCalculator { int add(int i, int j); int 

Spring AOP基础之JDK动态代理

JDK动态代理 Jdk动态代理是装饰模式的一个典型用例,关于装饰模式这里不多解释,直接说重点吧.jdk动态代理实际上就是代替继承方案,在不破坏原始类的原则下,在运行期间为某个类动态注入一些新的方法.java.lang.reflect.Proxy提供了生成代理类的接口.进入源代码,我们可以看见关于Proxy的详细说明这里截取一些关键的部分: /** * {@code Proxy} provides static methods for creating dynamic proxy * classe

Spring笔记(三)AOP前篇之动态代理

AOP思想是将程序中的业务代码与服务代码进行分离,在运行时进行结合.比较强调程序的层次结构,是一种面向切面的编程.而在AOP实现的底层主要用到了动态代理,而动态代理又分为JDK动态代理和CGLIB动态代理,两者的区别是JDK动态代理的实现中业务类必须必须定义接口,而CGLIB没有这个约束,可以说CGLIB更强大: JDK动态代理实现示例: // 业务接口定义 public interface IUnit {     void execute(String msg); } // 业务实现类 pub

AOP学习心得&amp;jdk动态代理与cglib比较

什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入封装.继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合.当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力.也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系.例如日志功能.日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无

Spring容器AOP的理解

一句话理解:根据被代理对象信息通过Proxy动态生成我们具体的代理类. 实现就动态代理.那动态代理是什么呢? 动态代理其实并不是什么新鲜的东西,学过设计模式的人都应该知道代理模式,代理模式就是一种静态代理.而动态代理就是利用反射和动态编译将代理模式变成动态的.原理跟动态注入一样,代理模式在编译的时候就已经确定代理类将要代理谁,而动态代理在运行的时候才知道自己要代理谁. 别说不知道静态代理?规则:一般静态代理类需要和被代理类实现同样的接口.就说这么多吧,还是进入今天的核心吧. JDK动态代理实现思