@@ -199,7 +199,6 @@ Spring的AOP只支持方法级别的调用,所以其实在AopProxy里,我们
199
199
}
200
200
```
201
201
202
-
203
202
## 8.step8-使用AspectJ管理切面
204
203
git checkout step-8-invite-pointcut-and-aspectj
205
204
@@ -234,4 +233,50 @@ aspect PointObserving {
234
233
}
235
234
```
236
235
237
- ## 9.
236
+ ## 9.step9-将AOP融入Bean的创建过程
237
+ git checkout step-9-auto-create-aop-proxy
238
+
239
+ 万事俱备,只欠东风!现在我们有了Pointcut和Weave技术,一个AOP已经算是完成了,但是它还没有结合到Spring中去。怎么进行结合呢?Spring给了一个巧妙的答案:使用` BeanPostProcessor ` 。
240
+
241
+ BeanPostProcessor是BeanFactory提供的,在Bean初始化过程中进行扩展的接口。只要你的Bean实现了` BeanPostProcessor ` 接口,那么Spring在初始化时,会优先找到它们,并且在Bean的初始化过程中,调用这个接口,从而实现对BeanFactory核心无侵入的扩展。
242
+
243
+ 那么我们的AOP是怎么实现的呢?我们知道,在AOP的xml配置中,我们会写这样一句话:
244
+
245
+ ``` xml
246
+ <aop : aspectj-autoproxy />
247
+ ```
248
+
249
+ 它其实相当于:
250
+
251
+ ``` xml
252
+ <bean id =" autoProxyCreator" class =" org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator" ></bean >
253
+ ```
254
+
255
+ ` AspectJAwareAdvisorAutoProxyCreator ` 就是AspectJ方式实现织入的核心。它其实是一个BeanPostProcessor。在这里它会扫描所有Pointcut,并对bean做织入。
256
+
257
+ 为了简化xml配置,我在tiny-spring中直接使用Bean的方式,而不是用aop前缀进行配置:
258
+
259
+ ``` xml
260
+ <bean id =" autoProxyCreator" class =" us.codecraft.tinyioc.aop.AspectJAwareAdvisorAutoProxyCreator" ></bean >
261
+
262
+ <bean id =" timeInterceptor" class =" us.codecraft.tinyioc.aop.TimerInterceptor" ></bean >
263
+
264
+ <bean id =" aspectjAspect" class =" us.codecraft.tinyioc.aop.AspectJExpressionPointcutAdvisor" >
265
+ <property name =" advice" ref =" timeInterceptor" ></property >
266
+ <property name =" expression" value =" execution(* us.codecraft.tinyioc.*.*(..))" ></property >
267
+ </bean >
268
+ ```
269
+
270
+ ` TimerInterceptor ` 实现了` MethodInterceptor ` (实际上Spring中还有` Advice ` 这样一个角色,为了简单,就直接用MethodInterceptor了)。
271
+
272
+ 至此,一个AOP基本完工。
273
+
274
+
275
+ ## 10.step10-使用CGLib进行类的织入
276
+ git checkout step-10-invite-cglib-and-aopproxy-factory
277
+
278
+ 前面的JDK动态代理只能对接口进行代理,对于类则无能为力。这里我们需要一些字节码操作技术。这方面大概有几种选择:` ASM ` ,` CGLib ` 和` javassist ` ,后两者是对` ASM ` 的封装。Spring中使用了CGLib。
279
+
280
+ 在这一步,我们还要定义一个工厂类` ProxyFactory ` ,用于根据TargetSource类型自动创建代理,这样就需要在调用者代码中去进行判断。
281
+
282
+ 另外我们实现了` Cglib2AopProxy ` ,使用方式和` JdkDynamicAopProxy ` 是完全相同的。
0 commit comments