作为【死磕Spring AOP】系列的第一篇, 这个系列是AOP源码分析级别的文章。由于现在AOP已经不是什么高深的技术,网上的例子也比比皆是,不论是xml schema,还是annotation声明式。相信用过Spring的朋友,都可以信手拈来。
本系列文章的原则
如何配置AOP不是重点
AOP相关概念讲解不是重点
AOP 底层代码设计才是重点
本篇的主要内容
认识ProxyFactory,并通过该工厂类,将“日志”和“安全校验”代码切入到业务逻辑中
分析代理对象的实现流程。
认识ProxyFactory相关对象
1.使用ProxyFactory,实现"AOP"效果
/** *模拟业务接口 */ public interface UserService { public void updateUser(); } /** *模拟具体业务 */ public class UserServiceImpl implements UserService{ @Override public void updateUser() { System.out.println("$$$$$$执行业务逻辑$$$$$"); } } /** * 模拟切面1 */ public class SecurityInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("==========执行安全校验===================="); return methodInvocation.proceed(); } } /** * 模拟切面2 */ public class LoggerBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("=======保存更新日志========="); } }
Main类
public static void main(String[] args) { //1.初始化源对象(一定要实现接口) UserService target =new UserServiceImpl(); //2.AOP 代理工厂 ProxyFactory pf = new ProxyFactory(target); //3.装配Advice pf.addAdvice(new SecurityInterceptor()); //pf.addAdvice(new LoggerBeforeAdvice()); pf.addAdvisor(new DefaultPointcutAdvisor(new LoggerBeforeAdvice())); ////4.获取代理对象 UserService proxy =(UserService)pf.getProxy(); //5.调用业务 proxy.updateUser(); }
输出结果
==========执行安全校验====================
=======保存更新日志=========
$$$$$$执行业务逻辑$$$$$
通过结果确认,通过编程的方式实现了AOP切入的效果。逻辑很简单,无需过多解释。把重点放到ProxyFactory对象上。下面,重点分析下ProxyFactory。
2.分析ProxyFactory
ProxyFactory继承了ProxyCreatorSupport类,持有了AopProxyFactory,AdvisorChainFactory,
List<Advisor>。等
类 | 作用 |
AopProxyFactory | 基于 AdvisedSupport 配置信息,生成AOP 代理对象.默认为“DefaultAopProxyFactory” |
AdvisorChainFactory | advisor链。默认实现为DefaultAdvisorChainFactory,只有一个方法,获取Advised满足条件的MethodInterceptor列表或DynamicInterceptionAdvice列表 |
Advisor | 持有AOP advice和filter |
ProxyConfig | 生成代理对象的配置元信息 |
3.AOP重点接口大杂烩
3.1Advice&Interceptor
Interceptor VS Advice
Advice是AOP编程中某一个方面(Aspect)在某个连接点(JoinPoint)所执行的特定动作,这个连接点(JoinPoint)可以是自 定义的;而Spring中的Interceptor更多关注程序运行时某些特定连接点(属性访问,对象构造,方法调用)时的动作。确切的 说,Interceptor的范围更窄一些。
3.2 PointCut&Advisor
概念列表
Terms | Description |
Aspect | A module which has a set of APIs providing cross-cutting requirements. For example, a logging module would be called AOP aspect for logging. An application can have any number of aspects depending on the requirement. |
Join point | This represents a point in your application where you can plug-in AOP aspect. You can also say, it is the actual place in the application where an action will be taken using Spring AOP framework. |
Advice | This is the actual action to be taken either before or after the method execution. This is actual piece of code that is invoked during program execution by Spring AOP framework. |
Pointcut | This is a set of one or more joinpoints where an advice should be executed. You can specify pointcuts using expressions or patterns as we will see in our AOP examples. |
Introduction | An introduction allows you to add new methods or attributes to existing classes. |
Target object | The object being advised by one or more aspects, this object will always be a proxied object. Also referred to as the advised object. |
Weaving | Weaving is the process of linking aspects with other application types or objects to create an advised object. This can be done at compile time, load time, or at runtime. |
3.4Proxy&ProxyFactory
4. ProxyFactory底层实现设计
弄清楚ProxyFactory的底层实现,也就基本上弄清了AOP的实现原理,不管使用XML Schema还是Annotation方式,归根结底核心就在这儿。主要差别,仅仅是使用PointCut差别而已。
Advisor是设计的核心元素,起到承上启下的作用,连接着Advice和Pointcut。默认实现是:DefaultPointCutAdvisor。需要知道2个接口ClassFilter,MethodMatcher,通过方法名,就可以判定他们的作用了,主要用在"匹配"上。
序列图
通过该序列图,可以清楚了解,代理的调用过程。整个过程就是围绕一个核心,构造匹配元素+反射调用。如果想搞清楚底层代理调用实现,可以看org.springframework.aop.framework .ReflectiveMethodInvocation。
接下来,将分析Spring Bean工厂是如何生成代理Bean的,以DefaultAdvisorAutoProxyCreator类为例,进行分析。
本文出自 “简单” 博客,请务必保留此出处http://dba10g.blog.51cto.com/764602/1785667
原文地址:http://dba10g.blog.51cto.com/764602/1785667