目录
2、AnnotationAwareAspectJAutoProxyCreator继承体系深入研究
一、用注解方式开启AOP
1、实例
(1)pom导入AOP模块
<!--AOP-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
(2)定义业务逻辑类(MathCalculator)
package com.xiang.spring.aop;
public class MathCalculator {
public int div(int i, int j) {
return i/j;
}
}
(3)定义日志切面类(LogAspect)
package com.xiang.spring.aop;
import jdk.nashorn.internal.scripts.JO;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
// 告诉spring,当前类是一个切面类
@Aspect
public class LogAspect {
/**
* aspect表达式:为MathCalculator类的任意方法:public int com.xiang.spring.aop.MathCalculator.*(..)
* 抽取公共的切入点表达式
* 如果在本类引用,直接写方法名即可:@Before("pointCurt()")
* 其他的切面引用,需要写方法的全名
*/
@Pointcut("execution(public int com.xiang.spring.aop.MathCalculator.div(int, int))")
public void pointCurt() {}
/**
* 前置通知(@Before):logStart:在目标方法运行之前运行
*
*/
@Before("pointCurt()")
public void logStart(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();// 方法名
Object[] args = joinPoint.getArgs();// 参数列表
System.out.println(name + "除法运行。。。参数列表是" + Arrays.asList(args));
}
/**
* 后置通知(@After):logEnd:在目标方法运行结束之后运行
* 无论方法是正常结束还是异常结束
*/
@After("pointCurt()")
public void logEnd(JoinPoint joinPoint) {
System.out.println("除法结束。。。");
}
/**
* JoinPoint 参数一定要出现在参数表的第一位,否则会出错
*/
@AfterReturning(value = "pointCurt()", returning = "result")
public void logReturn(JoinPoint joinPoint, Object result) {
// 获取方法返回值
System.out.println("除法正常返回。。。运行计算结果" + result);
}
@AfterThrowing(value = "pointCurt()", throwing = "exception")
public void logException(JoinPoint joinPoint, Exception exception) {
System.out.println("除法异常。。。异常信息" + exception);
}
/**
* 环绕通知,返回Object类型
*/
@Around("pointCurt()")
public Object logAround(ProceedingJoinPoint pjp) {
Object rtValue = null;
try {
Object[] args = pjp.getArgs();
// 执行前置通知
System.out.println("logAround before");
rtValue = pjp.proceed(args); // 执行拦截方法
// 执行后置通知
System.out.println("logAround after");
} catch (Throwable e) {
// 执行异常通知
System.out.println("logAround error");
} finally {
// 执行最终通知
System.out.println("logAround finally");
}
return rtValue;
}
}
(4)定义配置类
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
// 业务逻辑类加入容器中
@Bean
public MathCalculator mathCalculator() {
return new MathCalculator();
}
// 切面类加入容器中
@Bean
public LogAspect logAspect() {
return new LogAspect();
}
}
(5)创建测试类
import com.xiang.spring.aop.MathCalculator;
import com.xiang.spring.config.MainConfigOfAOP;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class IOCTest_AOP {
@Test
public void test01() {
// 创建ioc容器,容器创建时,默认会将单例的bean都创建出来
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
System.out.println(mathCalculator.div(2, 1));
System.out.println(mathCalculator.div(2, 0));
}
}
// 执行结果
div除法运行。。。参数列表是[2, 1]
除法结束。。。
除法正常返回。。。运行计算结果2
2
div除法运行。。。参数列表是[2, 0]
除法结束。。。
除法异常。。。异常信息java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
2、AOP简单小结
AOP:【动态代理】
指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式
(1).导入AOP模块-(spring-aspects)
(2).定义业务逻辑类(MathCalculator):在业务逻辑运行的时候,将日志进行打印(方法之前、方法执行后、方法出现异常时)。
(3).定义一个日志切面类(LogAspect):切面类里面的方法需要动态感知MathCalculator.div运行到哪里,然后执行。
通知方法:
前置通知(@Before):logStart:在目标方法运行之前运行
后置通知(@After):logEnd:在目标方法运行结束之后运行
返回通知(@AfterReturning):logReturn:在目标方法正常返回之后运行
异常通知(@AfterThrowing):logException:在目标方法运行出现异常之后运行
环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.proced)
(4).给切面类目标方法标注何时何地运行(通知注解)
(5).将切面类和目标业务逻辑类(目标方法所在类),都加入到容器中。
(6).必须告诉spring,哪个类是切面类。给切面类上加一个注解@Aspect
(7).在配置类中加@EnableAspectJAutoProxy,启用基于注解的aop模式。
在spring中,有很多的@EnableXxxxx,是开启某个功能注解。
总体来说分三步:
1.业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)。
2.在切面类上每个通知方法上都标注通知注解,告诉spring何时何地运行(写好切入点表达式)。
3.开启基于注解的AOP模式(@EnableAspectJAutoProxy)。
二、AOP原理
1、@EnableAspectJAutoProxy溯源
(1)@EnableAspectJAutoProxy导入了AspectJAutoProxyRegistrar组件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
(2)AspectJAutoProxyRegistrar组件源码
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
我们可以看到有一行代码AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
利用AspectJAutoProxyRegistrar自定义给容器中注册bean。
点进去可以看到,实际是给容器中注册一个组件名称为internalAutoProxyCreator,组件类型为AnnotationAwareAspectJAutoProxyCreator(自动代理创建器)的组件。
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
(3)AnnotationAwareAspectJAutoProxyCreator的继承体系
AnnotationAwareAspectJAutoProxyCreator
extends AspectJAwareAdvisorAutoProxyCreator
extends AbstractAdvisorAutoProxyCreator
extends AbstractAutoProxyCreator
extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
SmartInstantiationAwareBeanPostProcessor - > BeanPostProcessor:后置处理器,在bean初始化完成前后做的事情
BeanFactoryAware:自动装配BeanFactory
2、AnnotationAwareAspectJAutoProxyCreator继承体系深入研究
(1)关键方法分析
AbstractAutoProxyCreator.setBeanFactory BeanFactoryAware的重写方法
AbstractAutoProxyCreator.postProcessBeforeInstantiation 有后置处理器的逻辑
AbstractAdvisorAutoProxyCreator 重写了setBeanFactory ,会调用initBeanFactory
AnnotationAwareAspectJAutoProxyCreator 会重写 initBeanFactory
(2)创建和注册AnnotationAwareAspectJAutoProxyCreator的过程
① 传入配置类,创建ioc容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
② 注册配置类,调用refresh()刷新容器
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
③ 注册bean的后置处理器来方便拦截bean的创建
@Override
public void refresh() throws BeansException, IllegalStateException {
……
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
……
}
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// ① 先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// ② 给容器中加别的BeanPostProcessor
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// ③ 分离BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 优先注册实现了PriorityOrdered接口的BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 再给容器中注册实现了Ordered接口的BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 然后,注册没实现优先级接口的BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 把BeanPostProcessor注册到BeanFactory中:就是调用beanFactory.addBeanPostProcessor(postProcessor);
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
/**
上面注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中。
创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
(1)创建Bean的实例。
(2)populateBean:给bean的各种属性赋值
(3)initializeBean:初始化bean。
1)invokeAwareMethods():处理Aware接口的方法回调。
2)applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessorBeforeInitialization()
3)invokeInitMethods():执行初始化方法
4)applyBeanPostProcessorsAfterInitialization():执行后置处理器的postProcessorAfterInitialization()
(4)BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;容器中有了aspectJAdvisorsBuilder
*/
④ 完成beanFactory初始化工作,创建剩下的单实例bean
@Override
public void refresh() throws BeansException, IllegalStateException {
……
// 完成beanFactory初始化工作,创建剩下的单实例bean。
finishBeanFactoryInitialization(beanFactory);
……
}
(1)遍历获取容器中所有的Bean,依次创建对象getBean(beanName)。
getBean(beanName) -> doGetBean() -> getSingleton() ->
(2)创建bean
1)先从缓存中获取当前bean,如果能获取到,说明bean之前被创建过的,直接使用。否则获取不到再创建。只要创建好的bean都会被缓存起来。
2)createBean(); 创建bean,AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前先尝试返回bean实例。
① resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation
希望后置处理器在此能返回一个代理对象,如果能返回代理对象就使用,如果不能就继续调用doCreateBean()创建bean。
② doCreateBean(beanName, mbdToUse, args);真正的去创建一个bean实例,和上面创建bean的流程是一样的。
⑤ 创建bean时,尝试返回代理对象
其中,AbstractAutoProxyCreator是InstantiationAwareBeanPostProcessor的后置处理器,在这里就会创建一个代理对象。
而AnnotationAwareAspectJAutoProxyCreator继承于AbstractAutoProxyCreator,AnnotationAwareAspectJAutoProxyCreator又是@EnableAspectJAutoProxy会注册的bean。
区别于BeanPostProcessor:
BeanPostProcessor是在Bean对象创建完成初始化前后调用的。
InstantiationAwareBeanPostProcessor是在创建bean实例之前先尝试用后置处理器返回对象。
后置处理器先尝试返回对象,bean = applyBeanPostProcessorsBeforeInstantiation()
拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor,就执行后置处理器的postProcessBeforeInstantiation
后置处理器先尝试返回对象,bean = applyBeanPostProcessorsAfterInstantiation()
3、创建AOP代理
(1)AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用
1) 每一个bean创建之前,调用postProcessBeforeInstantiation()
关心MathCalculator和LogAspect的创建
① 判断当前bean是否在advisedBeans中(保存了所有需要增强的bean)
② 判断当前bean是否是基础类型的(Advice、Pointcut、Advisor、AopInfrastructureBean),或者是否是切面(@Aspect)
③ 判断是否需要跳过。
① 获取候选的增强器(切面里的通知方法)【List<Advisor> candidateAdvisors】
每一个封装的通知方法的增强器是InstantiationModelAwarePointcutAdvisor;
判断每一个增强器是否是AspectJPointcutAdvisor类型的,返回true。
② 永远返回false。
2)创建对象,调用postProcessAfterInstantiation()
return wrapIfNecessary(bean, beanName, cacheKey); // 包装如果需要的情况下。
① 获取当前bean的所有增强器(通知方法),封装成Object[] specificInterceptors
① 找到候选的所有的增强器(哪些通知方法是需要切入当前方法的)。
② 获取到能在当前bean使用的增强器。
③ 给增强器排序。
② 保存当前bean在advisedBeans中。
③ 如果当前bean需要增强,创建当前bean的代理对象。
① 获取所有增强器(通知方法)。
② 保存到proxyFactroy中。
③ 创建代理对象,spring自动决定,是创建jdk动态代理还是cglib的动态代理(JdkDynamicAopProxy、ObjenesisCglibAopProxy)。
④ 给容器中返回当前组件使用cglib增强了的代理对象。
⑤ 以后容器中获取到的就是组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程。
(2)AbstractAutoProxyCreator的postProcessBeforeInstantiation方法
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
(3)AbstractAutoProxyCreator.wrapIfNecessary()方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return 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;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
4、目标对象的目标方法执行流程(拦截器链获取)
容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器、目标对象等等 )。
1)CglibAopProxy.intercept();拦截目标方法的执行
2)根据ProxyFactory对象获取将要执行的目标方法拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
① 创建List<Object> interceptorList来保存所有拦截器,长度为5
一个默认的ExposeInvocationInterceptor 和4个增强器。
② 遍历所有的增强器,将其转为interceptor:registry.getInterceptors(advisor);
③将增强器转为 List<MethodInterceptor>
如果是MethodInterceptor,直接加入到集合中。
如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor。
返回MethodInterceptor数组。
3)如果没有拦截器链,直接执行目标方法。
拦截器链(每一个通知方法又被包装为方法的拦截器,利用MethodInterceptor机制)
4)如果有拦截器链,把需要执行的目标对象、目标方法、拦截器链等所有信息传入创建的CglibMethodInvocation对象并调用proceed()方法。
(1)CglibAopProxy.intercept();
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
(2)获取拦截器链DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
5、拦截器链的触发过程
拦截器链:
执行CglibMethodInvocation对象的proceed方法。
new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
1)如果没有拦截器直接执行目标方法;或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法。
currentInterceptorIndex记录当前拦截器的索引,从-1开始。
每次执行proceed()索引都会自增一次。
dm.interceptor.invoke(this); 也就是调用了CglibMethodInvocation的proceed方法。
2)链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器它是等待下一个拦截器执行完成返回以后再来执行。
拦截器链的机制,保证通知方法与目标方法的执行顺序。
(1)CglibMethodInvocation的proceed方法
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 如果没有拦截器链,就会直接执行目标方法 。
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
(2)AspectJAfterThrowingAdvice的invoke方法
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
(3)AfterReturningAdviceInterceptor的invoke方法
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
(4)AspectJAfterAdvice的invoke方法
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
(5)MethodBeforeAdviceInterceptor的invoke方法
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
(6)ExposeInvocationInterceptor的invoke方法
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
三、AOP总结
1.AOP小结
(1)@EnableAspectJAutoProxy开启AOP功能。
(2)@EnableAspectJAutoProxy会给容器中注册一个组件,AnnotationAwareAspectJAutoProxyCreator。
(3)AnnotationAwareAspectJAutoProxyCreator是一个后置处理器。
(4)容器的创建流程
① registerBeanPostProcessors()注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator对象。
② finishBeanFactoryInitialization() 初始化剩下的单实例bean。
① 创建业务逻辑组件和切面组件。
② AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
③ 在组件创建完成之后,判断组件是否需要增强。
是:切面的通知方法,包装成增强器(Advisor),给业务逻辑组件创建一个代理对象。
(5)执行目标方法(代理对象执行目标方法)
① CglibAopProxy.intercept();进行拦截
① 得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
② 利用拦截器的链式机制,依次进入每一个拦截器进行执行。
③ 执行顺序:前置通知 -> 目标方法 -> 后置通知 ->返回通知/异常通知