【spring】 spring aop 的使用与实现

描述 spring aop 的使用方法以及 spring 如何实现 aop 功能

基本概念

AOP 即 Aspect Oriented Programming,它是在不修改源代码的情况下给程序动态统一添加功能的一种技术。 AOP 的术语有

  • 通知(或叫增强) Advice
    想要通过 spring aop 增强的功能, 例如日志,事务,安全等
  • 增强器 Advicsor
    实现增强的功能。例如要实现日志,则需要实现了日志功能的增强器
  • 连接点 JoinPoint
    spring 中允许使用通知的地方,例如方法执行前,方法执行后
  • 切入点 Pointcut
    定义在连接点的基础上,例如一个类有 15 个方法,但并不是每一个方法都需要通知,切点就是为了筛选出连接点,选中要通知的方法
  • 切面 Aspect
    切面是通知和切入点的结合
  • 引入 Introduction
    允许向现有的类添加新方法属性
  • 目标 Target
    引入中所提到的目标类
  • 代理 proxy
    用来实现整个 AOP 的基础技术,spring aop 目前有 CGLIB 和 JDK 动态代理
  • 织入 weaving
    把切面应用到目标对象来创建新的代理对象的过程。spring 默认情况下是动态织入,即运行时织入。另外还有静态织入(即 jvm 启动时织入)和 LTW(即类加载时织入)

使用 spring aop

xml 方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class AopDemo {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");

HelloService helloService = ctx.getBean("helloService", HelloService.class);
helloService.hello();
}
}

// 服务类
public class HelloService {
public void hello() {
System.out.println("hello world!");
}
}

// 只定义方法
public class MethodLogAop {
public void before() {
System.out.println("before");
}

public void after() {
System.out.println("after");
}
}

// 实现 Advice 接口的 advisor
public class BeforeLogAdvisor implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("BeforeLogAdvisor");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">

<bean id="helloService" class="io.deer.xml.HelloService" />
<bean id="methodLogAop" class="io.deer.xml.MethodLogAop" />
<bean id="beforeLogAdvisor" class="io.deer.xml.BeforeLogAdvisor" />

<!-- aop 配置 -->
<aop:config>
<!-- 两种配置方式 -->
<!-- 一种是分别配置 pointcut 和 advisor -->
<aop:pointcut id="advisor" expression="execution(* io.deer.xml.*.*(..))"/>
<aop:advisor advice-ref="methodLogAop" pointcut-ref="advisor"/>

<!-- 另一种是配置 aspect, 在 aspect 内部配置 pointcut 和 advisor -->
<aop:aspect id="log" ref="methodLogAop">
<aop:pointcut id="hello" expression="execution(* io.deer.xml.HelloService.*(..))" />
<aop:before method="before" pointcut-ref="hello" />
<aop:after method="after" pointcut-ref="hello" />
</aop:aspect>
</aop:config>
</beans>

aspectj 注解方式

通过 @Aspect 注解的方式配置 aop 功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

// 入口类, 打开 aop 功能和定义 bean
public class AopDemo {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);

HelloService hello = ctx.getBean("helloService", HelloService.class);
hello.hello();
}

@Configuration
@EnableAspectJAutoProxy // 打开 aop 功能
static class Config {
// 定义服务 bean
@Bean
public HelloService helloService() {
return new HelloService();
}

// 定义切面
@Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor();
}
}
}

// 服务
public class HelloService {
public void hello() {
System.out.println("hello world!");
}
}

// 切面
@Aspect
public class MyInterceptor {

// 定义切入点(Pointcut),表式 io.deer.annota.HelloService 类的所有方法
@Pointcut("execution(* io.deer.annota.HelloService.*(..))")
public void MyPointCut() {}

// 定义连接点以及增强的功能,这里是打印一句日志
@Before("MyPointCut()")
public void before() {
System.out.println("MyInterceptor before");
}

}

编程方式

通过编程的方式实现 aop, spring 的功能就是通过这种方式实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class AopDemo {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");

HelloService helloService = ctx.getBean("helloService", HelloService.class);
helloService.hello();
}

@Configuration
@EnableAspectJAutoProxy
static class Config {
}
}

// 自定义的注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyLogAnnotation {
}

// 增强器
public class MyLogAdvisor extends AbstractPointcutAdvisor {

// 定义 point cut, 匹配有 @MyLogAnnotation 的方法
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return method.isAnnotationPresent(MyLogAnnotation.class);
}
};
}

// 定义增强,原方法调用前后打印日志
@Override
public Advice getAdvice() {
return new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before my log");
Object ret = invocation.proceed();
System.out.println("after my log");
return ret;
}
};
}
}

// 服务类
public class HelloService {

// 添加自定义的增强
@MyLogAnnotation
public void hello() {
System.out.println("hello world!");
}
}

自定义方式

允许用户自定义 AOP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

// 入口类
public class AopDemo {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);

HelloService hello = ctx.getBean("helloService", HelloService.class);
hello.hello();
}

@Configuration
@EnableAspectJAutoProxy
static class Config {
@Bean
public MyAdvisingBeanPostProcessor processor() {
return new MyAdvisingBeanPostProcessor();
}

@Bean
public HelloService helloService() {
return new HelloService();
}
}
}

// 服务类
public class HelloService {
public void hello() {
System.out.println("hello world!");
}
}

// 定义增强的 BPP
// AbstractAdvisingBeanPostProcessor 是一个专门用来做 AOP 的 BPP, 用户只需要设置它的 advisor 成员
public class MyAdvisingBeanPostProcessor extends AbstractAdvisingBeanPostProcessor {
public MyAdvisingBeanPostProcessor() {
// 定义一个 advisor
// NameMatchMethodPointcutAdvisor 是一种按方法名匹配的 advisor
NameMatchMethodPointcutAdvisor advisor = new NameMatchMethodPointcutAdvisor();
advisor.setMappedName("hello");
advisor.setAdvice(new AfterReturningAdvice(){
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
System.out.println("after returning");
}
});

// 设置 advisor 成员
this.advisor = advisor;
}
}

实现

打开 aop 功能

通过 @EnableAspectJAutoProxy 注解或 XML 的 <aop:config> 都可以打开 aop 功能。 两种方式分别将 AnnotationAwareAspectJAutoProxyCreator 和 AspectJAwareAdvisorAutoProxyCreator 注册到 bean factory。

AnnotationAwareAspectJAutoProxyCreator 是 AspectJAwareAdvisorAutoProxyCreator 的子类, AspectJAwareAdvisorAutoProxyCreator 实现了 SmartInstantiationAwareBeanPostProcessor 接口(BPP),重载 postProcessAfterInitialization 方法实现对 bean 的包装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

...

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 关键, 用 proxy 包装原来的 bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

// 用 proxy 包装 bean
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {

// 下面几类情况就返回 bean
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// advisedBeans 保存处理过的 bean
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// 获取所有可以应用到这个 bean 的增强器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 加入记录
this.advisedBeans.put(cacheKey, Boolean.TRUE);

// 创建代理
Object proxy = createProxy(
bean.getClass(), // bean 的原类名
beanName, // bean 名
specificInterceptors, // 增强器
new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

// 加入记录
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// 获取所有可以应用到这个 bean 的增强器
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY; // null,用来表示不创建 proxy
}
return advisors.toArray();
}

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 从 bean factory 找出所有 Advisor 类和所有 AspectJ 注解生成的 Advisor(即有 @Aspect 的类)
List<Advisor> candidateAdvisors = findCandidateAdvisors();

// 根据 PointCut 过滤出可以应用到当前这个 bean 的 advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors,
beanClass, beanName);

// 如果是 AspectJ 注解生成的 Advisor, 再增加一个 ExposeInvocationInterceptor
// ExposeInvocationInterceptor 是一个将当前的 MethodInvocation 保存到 thread local 的 Interceptor
extendAdvisors(eligibleAdvisors);

// 根据 Order 排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
}

生成 proxy

proxy 通过 ProxyFactory 生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

...

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory,
beanName, beanClass);
}

// 用 ProxyFactory 创建 Proxy
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);

if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}

// 创建 proxy
return proxyFactory.getProxy(getProxyClassLoader());
}
}

public class ProxyFactory extends ProxyCreatorSupport {

...

public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}

protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}

public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory; // aopProxyFactory 是 DefaultAopProxyFactory 的实例
}

...
}

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

// 创建 AopProxy
// 如果是 JdkDynamicAopProxy, 就使用 JDK 的代理机制实现 proxy
// 如果是 ObjenesisCglibAopProxy, 就使用 CGLIB 实现 proxy
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() ||
config.isProxyTargetClass() ||
hasNoUserSuppliedProxyInterfaces(config)) {

Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}

// 基本上,接口用 JDK 代理实现 proxy, 类用 CGLIB 实现 proxy
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}

// CglibAopProxy 是 ObjenesisCglibAopProxy 的基类
class CglibAopProxy implements AopProxy, Serializable {

...

// 使用 CGLIB 创建 proxy
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
...

// rootClass 是要代理的类
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available
for creating a CGLIB proxy");

// 如果代理类本身就是 CGLIB 生成的, 需要做些处理
// 把原来的接口添加到 advised
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}

validateClassIfNecessary(proxySuperClass, classLoader);

// 开始配置 CGLIB 增强器
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 设置代理类
enhancer.setSuperclass(proxySuperClass);
// 设置接口
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
// 设置 CGLIB 生成的类名的策略,这里生成的类名都有 BySpringCGLIB 字样
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

// 设置 callback
// callback 是 CGLIB 中比较重要的概念,可以理解成生成的代理类的方法被调用时,会执行 callback 的代码
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}

// 设置 callback filter, 这个 filter 决定什么样的方式用哪个 callback 处理
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(),
this.fixedInterceptorMap,
this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);

// 用 enhancer.create() 创建代理实例对象
return createProxyClassAndInstance(enhancer, callbacks);
}

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// 以下 3 个变量用来做优化
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
// 如果是 singleton 的 bean, isStatic 总是 true
boolean isStatic = this.advised.getTargetSource().isStatic();

// 一般的 advice 都从这个 interceptor 入口
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}

// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) :
new SerializableNoOp());

Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // 调用增强的方法,这是一般情况
targetInterceptor, // 直接调用目标方法
new SerializableNoOp(), // 什么都不做,finalize 方法执行这个 callback
targetDispatcher, // 转发到代理目标对象执行,执行速度比 targetInterceptor 要快
this.advisedDispatcher, // 转发到 advisor 上执行,例如代理类是个 interface 且实现了 Advised 时就用这个执行
new EqualsInterceptor(this.advised), // equsls 方法执行这个 callback
new HashCodeInterceptor(this.advised) // hashCode 方法执行这个 callback
};

Callback[] callbacks;

// 如果是 static 并且 advice chain 被冻结,可以做一些优化:直接调用目标方法
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);

// 遍历所有方法
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(
methods[x], rootClass);
// 每个方法生成一个 FixedChainStaticTargetInterceptor
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(methods[x].toString(), x);
}

// 将 mainCallbacks 和 fixedCallbacks 合并
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
return callbacks;
}
}

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
// 找到增强的接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 用 JDK 的代理创建 proxy 对象
// this 是一个 InvocationHandler
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
}

被增强方法的调用

使用 CGLIB 创建代理的情况

代理方法的入口是 DynamicAdvisedInterceptor 的 intercept 方法。DynamicAdvisedInterceptor 是一个实现了 MethodInterceptor 接口的 CGLIB callback, 调用 CGLIB 生成的代理对象的方法时,一般情况下都先调用它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {

...

@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
throws Throwable {

Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// 处理 exposeProxy 为 true 的情况,先将 AopContext 里的 proxy 保存
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// target 是目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);

// 通过 DefaultAdvisorChainFactory 得到调用链
// chain 里包含所有适用于这个方法的增强器
// 通过 chain 可以调用到各个增强器的增强方法(职责链模式)
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;

// 如果 chain 是空就直接调用被代理的方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 调用增强器
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 处理返回 this 的情况
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
// 释放目标对象,它可能来自对象池
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}

if (setProxyContext) {
// 恢复 proxy
AopContext.setCurrentProxy(oldProxy);
}
}
}

...
}

private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
Object[] arguments, @Nullable Class<?> targetClass,
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy)

super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);

...
}
}

// CglibMethodInvocation 的基类
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {

protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method,
@Nullable Object[] arguments, @Nullable Class<?> targetClass,
List<Object> interceptorsAndDynamicMethodMatchers) {

this.proxy = proxy; // 代理对象
this.target = target; // 被代理对象
this.targetClass = targetClass; // 被代理的类
this.method = BridgeMethodResolver.findBridgedMethod(method); // 调用的方法
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments); // 调用参数
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers; // 增强器列表
}

...

@Override
@Nullable
public Object proceed() throws Throwable {
// currentInterceptorIndex 默认值是 -1
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}

// 取一个增强器
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;

Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
return proceed();
}
}
else {
// 调用增强器
// 这里传了 this 作为参数,所以增强器可以决定是递归调用 proceed 继续执行,还是中止执行
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
}

使用 JDK 创建代理的情况

使用 JDK 代理时, 所有调用方法都通过 InvocationHandler 处理,而 JdkDynamicAopProxy 本身就实现了 InvocationHandler 接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
// 处理 equals 和 hashCode 方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// 调用增强器的方法
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal;

// 保存 AopContext 里的 proxy
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

// target 是目标对象
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);

// 得到增强器列表
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

if (chain.isEmpty()) {
// 直接调用
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 调用增强器,同 CGLIB 的情况一样
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}

// 处理返回 this 的情况
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
// 释放目标对象,它可能来自对象池
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}

// 恢复 proxy
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}

示例

@Async 注解可以使得方法异步执行,而不影响方法的代码逻辑,这是 AOP 的一个典型应用,示例代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class AsyncDemoApp {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);

HelloService hello = ctx.getBean("helloService", HelloService.class);
hello.hello();
}

@Configuration
@EnableAsync // 打开 Async 功能
static class Config {
@Bean
public HelloService helloService() {
return new HelloService();
}
}
}

public class HelloService {
@Async // @Async 注解的方法将异步执行
public void hello() {
System.out.println("hello world!");
}
}

@EnableAsync 通过 @Import(AsyncConfigurationSelector.class) 实现,AsyncConfigurationSelector 根据配置在 bean factory 注册 ProxyAsyncConfiguration 或 AspectJAsyncConfiguration (使用 AspectJ)。 Configuration 分别注册 AsyncAnnotationBeanPostProcessor 和 AnnotationAsyncExecutionAspect

AsyncAnnotationBeanPostProcessor 是 AbstractAdvisingBeanPostProcessor 的子类,是一个给 bean 包装异步调用的 BPP,它的 advisor 是 AsyncAnnotationAdvisor,AsyncAnnotationAdvisor 的 pointcut 是 AnnotationMatchingPointcut,advice 是 AnnotationAsyncExecutionInterceptor。

当调用这些方法时,AnnotationAsyncExecutionInterceptor 就会新建一个调用 @Async 方法的 Callable 对象,然后提交到线程池去执行。