指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式
步骤
导入aop模块:Spring AOP(Spring-aspects)
定义业务逻辑类(MathCalculator):在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法正常返回等等)
-
定义日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator.div运行到哪儿了。通知方法:
前置通知(@Before):logStart(在目标方法(div)运行之前运行)
后置通知(@After):logEnd(在目标方法(div)运行结束之后运行)
返回通知(@AfterReturning):logReturning(在目标方法(div)正常返回之后运行)
异常通知(@AfterThrowing):logThrow(在目标方法(div)出现异常以后运行)
环绕通知(@Around):logAround (动态代理,手动推进目标方法运行ProceedingJoinPoint.proceed)
给切面类的目标方法标注何时运行(通知注解@Before等)
必须告诉Spring哪个类是切面类(给切面类上加注解:@Aspect)
将切面类和业务逻辑类(目标方法所在类)加入容器
给配置类中加 @EnableAspectJAutoProxy【开启基于注解的aop模式】。在Spring中有很多@Enablexxx(开始xxx的注解模式)
业务类
public class MathCalculator {
public int dev(int i, int j) {
System.out.println("MathCalculator。。。div");
return i/j;
}
}
日志切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
@Aspect // 告诉Spring这是一个切面类
public class LogAspects {
// 抽取公共的切入点表达式
@Pointcut("execution(public int test.aop.MathCalculator.*(..))")
public void pointCut() {
}
@Before("pointCut()")// 本类引用
public void logStart(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName() + "运行。。。参数列表是:{" + Arrays.toString(joinPoint.getArgs()) + "}");
}
@After("test.aop.LogAspects.pointCut()")// 其他的切面引用
public void logEnd(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName() + "结束。。。");
}
@AfterReturning(value = "pointCut()", returning = "result")
public void logReturn(JoinPoint joinPoint, int result) {
System.out.println(joinPoint.getSignature().getName() + "正常返回。。。返回值" + result);
}
@AfterThrowing(value = "pointCut()", throwing = "exception")
public void logThrow(JoinPoint joinPoint, Exception exception) {
System.out.println(joinPoint.getSignature().getName() + "异常。。。异常信息" + exception);
}
// JoinPoint 一定要出现在参数表的第一位,不然会报错
@Around("pointCut()")
public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
System.out.println(pjp.getSignature().getName() + "before around。。。参数值" + Arrays.toString(pjp.getArgs()));
Object proceed = pjp.proceed();
System.out.println(pjp.getSignature().getName() + "after around。。。返回值" + proceed);
return proceed;
}
}
配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import test.aop.LogAspects;
import test.aop.MathCalculator;
@Configuration
@ComponentScan("test.aop")
@EnableAspectJAutoProxy
public class ConfigOfAop {
@Bean
public MathCalculator mathCalculator() {
return new MathCalculator();
}
@Bean
public LogAspects logAspects() {
return new LogAspects();
}
}
启动类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigOfAop.class);
MathCalculator mathCalculator = context.getBean(MathCalculator.class);
mathCalculator.dev(1,1);
1/1 打印结果
devbefore around。。。参数值[1, 1]
dev运行。。。参数列表是:{[1, 1]}
MathCalculator。。。div
devafter around。。。返回值1
dev结束。。。
dev正常返回。。。返回值1
1/0 打印结果
devbefore around。。。参数值[1, 0]
dev运行。。。参数列表是:{[1, 0]}
MathCalculator。。。div
dev结束。。。
dev异常。。。异常信息java.lang.ArithmeticException: / by zero
Exception in thread "main" java.lang.ArithmeticException: / by zero
at test.aop.MathCalculator.dev(MathCalculator.java:8)
...
原理分析
- 先从 @EnableAspectJAutoProxy 注解分析
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
...
AspectJAutoProxyRegistrar继承了ImportBeanDefinitionRegistrar接口。手动注册bean到容器中。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
...
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注入bean到容器中
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
...
一直点击方法registerAspectJAnnotationAutoProxyCreatorIfNecessary->registerAspectJAnnotationAutoProxyCreatorIfNecessary->registerOrEscalateApcAsRequired
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
registerOrEscalateApcAsRequired方法把AnnotationAwareAspectJAutoProxyCreator注册到容器中,名字:org.springframework.aop.config.internalAutoProxyCreator
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
...
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;
}
- 再看看 AnnotationAwareAspectJAutoProxyCreator是干啥的
继承关系
AnnotationAwareAspectJAutoProxyCreator
->AspectJAwareAdvisorAutoProxyCreator
->AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor,BeanFactoryAware
ProxyProcessorSupport extends ProxyConfig implements Ordered
SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor
发现这个类是一个后置处理器(在bean初始化完成前后调用),会自动装配 BeanFactory,并实现了 Ordered
AbstractAutoProxyCreator 有BeanFactory装配、后置处理器逻辑
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
...
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
...
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
return true;
}
AbstractAdvisorAutoProxyCreator.setBeanFactory -> initBeanFactory
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
AnnotationAwareAspectJAutoProxyCreator.initBeanFactory 对
BeanFactory 进行一层包装成
ReflectiveAspectJAdvisorFactory
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
流程
- 传入配置类,创建ioc容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigOfAop.class);
- 注册配置类,调用 refresh() 刷新容器
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
- 注册 bean 的后置处理器来方便拦截 bean 的创建
public void refresh() throws BeansException, IllegalStateException {
...
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
....
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 1. 先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
...
// 2. 区分 实现了 PriorityOrdered、Ordered、没实现优先级 的BeanPostProcessor
// 3. 优先实现了 PriorityOrdered 接口的 BeanPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 4. 再给容器注册实现了 Ordered 的 BeanPostProcessor
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
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);
// 5. 注册没实现优先级接口的 BeanPostProcessor
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 6. 最后,重新注册所有内部 BeanPostProcessor。
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 重新注册后处理器以将内部bean检测为ApplicationListener,将其移至处理器链的末尾(用于拾取代理等)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
由于 AnnotationAwareAspectJAutoProxyCreator 是实现了 Ordered 的接口,会在第4步注册到容器中
- BeanPostProcessor 注册流程
注册 BeanPostProcessor,实际上就是创建 BeanPostProcessor 对象,保存在容器中。创建 org.springframework.aop.config.internalAutoProxyCreator 的 BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
beanFactory.getBean() -> doGetBean() -> createBean() -> doCreateBean()
先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;只要创建好的bean都会缓存起来
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...
// 认真检查单例缓存是否有手动注册的单例
Object sharedInstance = getSingleton(beanName);
...
// 创建 bean
return createBean(beanName, mbd, args);
...
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
...
// 给BeanPostProcessors一个返回代理而不是目标bean实例的机会
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
...
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
...
}
doCreateBean()
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
...
// 1. 创建 bean 的实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
...
// 2. 给 bean 的各种熟性赋值
populateBean(beanName, mbd, instanceWrapper);
// 3. 初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
...
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
...
}
initializeBean()
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
...
// 1. 处理 Aware接口的方法回调 比如 BeanFactoryAware(装配BeanFactory)
invokeAwareMethods(beanName, bean);
...
// 2. 执行后置处理器的postProcessBeforeInitialization() 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
...
// 3. 执行自定义的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
...
// 4. 执行后置处理器的 postProcessBeforeInitialization() 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
至此 AnnotationAwareAspectJAutoProxyCreator 创建完成;AnnotationAwareAspectJAutoProxyCreator【BeanPostProcessor】会注册到 BeanFactory中 beanFactory.addBeanPostProcessor(postProcessor);
- 业务类的创建流程和切面类的创建流程
public void refresh() throws BeansException, IllegalStateException {
...
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
...
// 实例化所有剩余的(非延迟初始化)单例。
finishBeanFactoryInitialization(beanFactory);
...
}
finishBeanFactoryInitialization() -> beanFactory.preInstantiateSingletons()
遍历获取容器中所有的Bean,依次创建对象 getBean(beanName)
@Override
public void preInstantiateSingletons() throws BeansException {
...
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
...
for (String beanName : beanNames) {
...
getBean(beanName);
...
}
}
beanFactory.getBean() -> doGetBean() -> createBean()
// 给BeanPostProcessors一个返回代理而不是目标bean实例的机会
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
resolveBeforeInstantiation 希望后置处理器在此返回一个代理对象,如果能返回代理对象就使用,如果不能就继续
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
...
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
...
}
拿到所有的后置处理器,如果是 InstantiationAwareBeanPostProcessor 就执行 postProcessBeforeInstantiation;而 AnnotationAwareAspectJAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor,在所有bean创建之前会有一个拦截,在任何 bean 创建之前尝试返回 bean 的实例
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
doCreateBean() 真正去创建一个 bean 实例;和上面 BeanPostProcessor 注册的创建流程一样
- AnnotationAwareAspectJAutoProxyCreator 的作用
postProcessBeforeInstantiation
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 1. 判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 2. 判断是否是基础类型的 Advice、Pointcut、Advisor、AopInfrastructureBean或者是否是切面(@Aspect)
// 3. 是否需要跳过
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 是否有自定义的 TargetSource
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
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;
}
shouldSkip 是否需要跳过
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 获取候选的增强器(切面里面的通知方法)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
// AspectJPointcutAdvisor 是否是这个类型
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
创建完对象执行 postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果需要包装
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
// 进行 postProcessBeforeInstantiation 一样的判断
...
// 获取当前bean的所有增强器(通知方法)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 保存在advisedBeans
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 如果当前bean需要增强,创建当前bean的代理对象
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;
}
getAdvicesAndAdvisorsForBean()->findEligibleAdvisors()
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 找到候选的增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// findAdvisorsThatCanApply->AopUtils.findAdvisorsThatCanApply()-> canApply()(解析切面表达式能不能匹配)
// 找到能在 bean 使用的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 给增强器进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
createProxy() -> proxyFactory.getProxy(getProxyClassLoader()) -> createAopProxy().getProxy(classLoader) -> getAopProxyFactory().createAopProxy(this)
创建代理对象:Spring 自动决定
JdkDynamicAopProxy: jdk 动态代理
ObjenesisCglibAopProxy:cglib 动态代理
以后容器中获取的就是这个组件的代理对象,执行目标方法的时候,代理对象会执行通知方法的流程
@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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
所以在默认情况下,如果一个目标对象如果实现了接口Spring则会选择JDK动态代理策略动态的创建一个接口实现类(动态代理类)来代理目标对象,可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出java.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现任何接口,Spring会选择CGLIB代理, 其生成的动态代理对象是目标类的子类。
上说的是默认情况下,也可以手动配置一些选项使Spring采用CGLIB代理。
org.springframework.transaction.interceptor.TransactionProxyFactoryBean是org.springframework.aop.framework. ProxyConfig的子类,所以可以参照ProxyConfig里的一些设置如下所示,将optimize和proxyTargetClass任意一个设置为true都可以强制Spring采用CGLIB代理。
如果当需要使用CGLIB代理和@AspectJ自动代理支持,请按照如下的方式设置 |aop:aspectj-autoproxy| 的 proxy-target-class 属性:
|aop:aspectj-autoproxy proxy-target-class="true"/|
如果是 JDK 代理,名字是类似$Proxy75
// Ss 是接口,用以下两种方式任意一种从容器中获取
Ss mathCalculator = (Ss) context.getBean("mathCalculator");
mathCalculator = context.getBean(Ss.class);
- 目标方法执行
容器保存了组件的代理对象(cglib/jdk增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象等待)
- CglibAopProxy.intercept() / JdkDynamicAopProxy.invoke() 拦截了目标方法的执行
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
...
// 获取将要执行的目标方法拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
...
// 没有拦截器,直接执行目标方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 如果有拦截器,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个 CglibMethodInvocation,然后执行
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
...
}
getInterceptorsAndDynamicInterceptionAdvice() -> advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
便利所有的增强器,将其转为 MethodInterceptor:registry.getInterceptors(advisor);
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
// 如果是MethodInterceptor,直接加入
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// 如果不是,利用 AdvisorAdapter将增强器转为 MethodInterceptor
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
增强器链的调用
CglibMethodInvocation.proceed();
链式获取每一个拦截器,拦截执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再执行。拦截器链的机制,保证通知方法与目标方法的执行顺序。
Override
@Nullable
public Object proceed() throws Throwable {
// 如果没有拦截器链执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(执行到了最后一个拦截器)执行目标方法
// 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;
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 {
// 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);
}
}
增强器链的流程图