先上代碼,比如我使用aspectj風格的注解,定義了一個針對naiveWaiter的切面邏輯
@Aspect
public class TestAspect {
/**
* 訪問連接點對象
*/
@Around("execution(* greetTo(..)) && target(com.brianway.learning.spring.aop.aspectj.NaiveWaiter)")
public void joinPointAccess(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("------joinPointAccess-------");
System.out.println("args[0]:" + pjp.getArgs()[0]);
System.out.println("target:" + pjp.getTarget());
System.out.println("signature:" + pjp.getSignature());
System.out.println("this:" + pjp.getThis());
pjp.proceed();
System.out.println("-------joinPointAccess-------");
}
測試類如下
@Test
public void testJoinPoint() {
String configPath = "com/brianway/learning/spring/aop/aspectj/beans-advanced.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(configPath);
Waiter naiveWaiter = (Waiter) context.getBean("naiveWaiter");
naiveWaiter.greetTo("Brian");
}
debug看一下這個naiveWaiter對象到底是什么

462722787.jpg
可以看到這個naiveWaiter對象其實是一個EnhancerBySpringCglib
并不是一個普通的NaiveWaiter對象,關(guān)鍵點就在這里。
當一個對象被SpringAOP代理,那么當使用getBean獲取到的并不是對象本身,而是一個代理對象。
那么之前的文章bean的生命周期中,這個代理的過程是在哪一步進行的呢
createBeanInstance
populateBean
initlizeBean
其實發(fā)生在initlizeBean,在其中會執(zhí)行BeanProcessor.postProcessAfterInitialization
具體就是AbstractAutoProxyCreator類的postProcessAfterInitialization 方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
執(zhí)行之后,返回的就是一個代理對象(代理對象包含一個Advisor數(shù)組,一個目標對象)
總結(jié)一下,Spring AOP動態(tài)代理的執(zhí)行過程如下
1.生成代理對象,初始化攔截器鏈(這發(fā)生在bean的生命周期initlizeBean中,生成是通過AopProxy接口,有兩個實現(xiàn)類Cglib2AopProxy,JdkDynamicAopProxy)
2.代碼中調(diào)用bean的某個方法的時候,實際上是通過代理對象調(diào)用的。調(diào)用時會獲取攔截器鏈,逐個進行匹配執(zhí)行(切面邏輯),最終通過反射的方法調(diào)用目標對象方法。