前言
本篇文章主要介绍AOP的源码,要想看懂AOP,那么就看AOP给容器中注入了什么组件,这个组件什么时候工作,这个组件的功能是什么?
@EnableAspectJAutoProxy
会向IOC容器中注入一个后置处理器,它会在Bean的创建过程进行加工- 当我们获取Bean的时候,因为已经存在Aop注入的后置处理器,会在Bean的创建阶段生成代理对象
- 最终生成的Bean代理对象,里面会是一个层层代理的链式结构,因为Aop里面的增强方法是存在顺序的,所以这里也是按照顺序执行
- 当调用目标方法的时候,就会按照顺序依次执行增强方法和目标方法
一、@EnableAspectJAutoProxy
1.注解引入了哪个类
当使用AOP的时候,会通过注解@EnableAspectJAutoProxy
来开启AOP,那么这个注解做了些什么呢?看一下其源码,发现通过@Import
注解引用了AspectJAutoProxyRegistrar.class
,其最终目的就是注入了这个类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class) // 在这里引入了一个类
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
AspectJAutoProxyRegistrar
是上面注解导入的一个类,它实现了ImportBeanDefinitionRegistrar
接口,该接口同样也是Spring提供的扩展点,它可以把自定义的BeanDefinition
注册到Spring容器中。
那么该类中主要做了2件事
- 通过
AopConfigUtils
注册了一个BeanDefinition
,具体为AnnotationAwareAspectJAutoProxyCreator
- 根据
@EnableAspectJAutoProxy
设置的属性,进行相应的操作
// 导入的这个类实现了 ImportBeanDefinitionRegistrar 接口
// 该接口可以将自定义的组件添加到容器中
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 通过Aop工具类 `注册切面注解自动代理创建器当其需要的时候` 这也是方法名的意思
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 获取@EnableAspectJAutoProxy注解的属性 在其注解里面可以设置2个属性
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
// 通过这2个属性 在进行响应的处理
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
上面的方法中看到会借助AopConfigUtils
类来注册BeanDefinition
,进入对应的方法里面可以看到注册的类为AnnotationAwareAspectJAutoProxyCreator
// 第1步:首先会调用到这里
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
// 第2步:再次会进入到这里
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
// 在这里看到注入的Bean为 AnnotationAwareAspectJAutoProxyCreator.class
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
// 第3步
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 判断是否包含这个名称为 internalAutoProxyCreator的Bean
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
// 获取到Bean
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
// 如果全限定类名是否相同 也就是上面的名字相同,那么需要在判断类型
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {// 当不相同的时候
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
// 判断优先级
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
// 不存在则创建Bean
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}
2.引入类介绍
通过上面的内容得知,@EnableAspectJAutoProxy
注解最终会向Bean的定义信息里面注册一个AnnotationAwareAspectJAutoProxyCreator
类,其对应的beanName
为org.springframework.aop.config.internalAutoProxyCreator
,
通过下面的类图可以看出,AnnotationAwareAspectJAutoProxyCreator
实现了BeanPostProcessor
,证明它是一个后置处理器,不仅需要把它注入到IOC容器中,还需要把它注入到BeanFactory
后置处理器集合中
> 注入到后置处理器集合中
实现逻辑的方法为refresh() -> registerBeanPostProcessors()
,它负责了2件事情:
- 把后置处理器存入IOC容器中,所有的bean都要注入到容器中,这是必须的
- 把后置处理器按照优先级规则存入
beanFactory
中
// PostProcessorRegistrationDelegate
// 下面的代码看着很长,其实仔细看很简单,主要就是注册后置处理器,但是需要按照优先级分成三组,顺序注册
// 大体的执行流程未:
// 1) 先获取IOC容器已经定义了的需要创建对象的所有BeanPostProcessor
// 2) 给容器中加别的BeanPostProcess
// 3) 优先注册实现了 PriorityOrdered接口的BeanPostProcessor
// 4) 再给容器中注册实现了Ordered接口的BeanPostProcessor
// 5) 注册没实现优先级接口的BeanPostProcessor
// 6) 注册BeanPostProcessor 实际上就是通过getBean()创建BeanPostProcessor对象,保存在容器中
// 7) 把BeanPostProcessor注册到BeanFactory中
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取到工厂里面的所有BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// 数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 遍历
for (String ppName : postProcessorNames) {
// 实现PriorityOrdered接口的后置处理器添加到priorityOrderedPostProcessors
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
// 实现MergedBeanDefinitionPostProcessor接口的添加到internalPostProcessors
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 实现Ordered接口的添加到orderedPostProcessorNames
// 像使用AOP需要注入的【AnnotationAwareAspectJAutoProxyCreator】在顶层实现了Ordered接口
// 所以会在这里
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
// 未实现排序的处理器
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 注册实现PriorityOrdered接口的后置处理器
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 注册实现Ordered接口的后置处理器
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);
// Now, register all regular BeanPostProcessors.
// 注册未实现排序的处理器
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 最终 注册实现MergedBeanDefinitionPostProcessor接口的
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).
// 重新注册后置处理器把内部Bean检测为ApplicationListeners
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
二、获取增强器
带着问题看源码
AOP底层是借助的后置处理器,这个已经说了很多遍了,上面介绍的AnnotationAwareAspectJAutoProxyCreator
类实现了BeanPostProcessor
,并且注入到容器中了,剩下的肯定使用,那么我们需要关心的无非是几个问题:
- 创建成AOP代理对象的方法入口在哪里?
- 获取该bean可以应用的增强器
- 代理对象创建过程
- 创建后的代理对象长啥样?
1.入口方法
既然是后置处理器,肯定是bean初始化的时候,会创建成代理对象,那么bean的初始化也分情况:
- 如果是普通的bean创建,那么会在
doCreateBean() -> initializeBean()
,当创建bean以后,初始化的时候,会执行对应的后置处理器 - 如果是循环依赖的bean创建,那么会在
doCreateBean() -> getEarlyBeanReference()
,在这里也会执行后置处理器
上面我在Debug源码的时候只试了这2种情况,可能还要其它的入口,但到不管有多少个入口,到最后都会到1个地方负责创建代理,那就是AnnotationAwareAspectJAutoProxyCreator
类,找到其重写后置处理器接口的方法就好了。
在源码翻阅的时候,发现其中并没有,但是在其父类AbstractAutoProxyCreator
,其中存在重写的postProcessAfterInitialization()
2.获取该bean可以应用的增强器
> 整体逻辑
AOP又给我们提供了各种类型的切面,当需要把bean给创建成代理对象,整体逻辑如下:
- 创建前需要存在各种特殊判断,判断这个bean到底是否需要创建代理对象,排除一些特殊情况,当判断通过,接下来就是开始创建代理
- 获取代码设置的全部增强器,还有各种切入点
Pointcut
,这些第一次获取以后肯定是缓存起来的 - 从全部的增强器中获取到该bean可以使用的增强器
- 对增强器进行排序
> wrapIfNecessary()
通过上面我们看到,创建代理对象都是走到AbstractAutoProxyCreator#wrapIfNecessary()
这个类的后置处理器方法中
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 根据给定bean的class和name构建出一个key,格式: beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 可能存在循环依赖,判断该bean是否已经提前暴露, 存在这里就不用创建代理对象了
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 适合被代理,则需求封装指定bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary()
这个方法通过名字也可以看出意思来,如果该bean可以被代理,那就创建
// 在这里面的类代表无须再次尝试创建AOP代理对象, 包括已经创建完的和不需要创建的
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1.如果已经处理过
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 2.代表该bean无需增强
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 3.bean的类是aop基础设施类 || bean应该跳过,则标记为无需处理,并返回
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 4.获取当前bean的Advices和Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 5.如果存在增强器则创建代理
if (specificInterceptors != DO_NOT_PROXY) {
// 代表该bean已经处理了
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建搭理
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 创建完代理后,将cacheKey -> 代理类的class放到缓存
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 6.标记为无需处理
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
> 不能创建代理对象前的特殊情况
在wrapIfNecessary()
前会有几个方法执行,负责判断是否可以把当前bean创建成代理对象,初始化的时候肯定会有一些特殊情况存在,需要特殊排除
isInfrastructureClass()
排除基础设置类
是否是基础配置类,一些固定的类不能被代理
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
// Previously we setProxyTargetClass(true) in the constructor, but that has too
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
// aspects. I'm not entirely happy with that as there is no good reason not
// to advise aspects, except that it causes advice invocation to go through a
// proxy, and if the aspect implements e.g the Ordered interface it will be
// proxied by that interface and fail at runtime as the advice method is not
// defined on the interface. We could potentially relax the restriction about
// not advising aspects in the future.
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
shouldSkip()
是否跳过创建
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
// 获取候选的增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
> 获取全部的增强器
继续回到wrapIfNecessary()
中,接下来会获取增强器,getAdvicesAndAdvisorsForBean()
获取指定bean的增强方法一定是包含两个步骤的:
- 获取所有的增强,通过
findCandidateAdvisors()
- 寻找所有增强中适用于该bean的增强并应用,通过
findAdvisorsThatCanApply()
// 获取当前Bean的所有增强器
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 获取增强方法
List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
// 获取到了则返回,获取不到返回null
return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}
// 获取到能在这个目标方法中匹配的增强器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 1)找到所有的增强器
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
// 2)从所有增强里面获取到能在bean使用的增强器
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 3.扩展方法,留个子类实现
this.extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 4.对符合条件的Advisor进行排序
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
a> findCandidateAdvisors() 获取全部增强器
- 通过调用父类方法,来解析通过XML配置的AOP
- 解析通过注解方式设置的AOP
- 将所有的封装成增强器返回
@Override
protected List<Advisor> findCandidateAdvisors() {
// 1)通过父类,加载对XML配置的AOP
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
// 2) 解析注解方式配置的AOP
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
b> buildAspectJAdvisors() 筛选AOP切面类
【方法功能】:既然要筛选切面类,那肯定要遍历项目,筛选出全部标记@Aspect
的切面类
上面方法中,会分别解析通过XML和注解配置的AOP,这里只介绍第2种,因为现在的开发更多的使用注解配置
那么就详细看一下buildAspectJAdvisors()
,该方法的整体逻辑为:
- 第一次获取,不存在增强器缓存的情况
- 获取所有在beanFactory中注册的beanName
- 遍历所有的beanName,并找出声明
@Aspect
注解的类- 如果是切面类是单例,则获取到该单例bean中的所有增强方法,然后存入缓存
- 其它情况,把当前BeanFactory和切面bean封装为一个多例类型的Factory,存入缓存
- 不是第一次获取,存在增强器缓存的情况
- 执行到这里,代表缓存中是存在的
- 首先从切面缓存中直接获取增强器,代表是一个单例的切面类
- 获取不到,则可能是多例,然后对应的
factory
,然后获取增强类
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
// 1.尝试从缓存中获取aspectNames,若没有则手动获取
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
// 加锁以后Double Check
if (aspectNames == null) {
// 返回结果
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 1.获取所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 2.遍历
for (String beanName : beanNames) {
// 不合法的bean则略过, 由子类重写方法定义规则
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
// 获取对应的bean类型
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 如果该bean存在@Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
// 把切面类封装成一个元数据类, 包含bean的树形
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 判断@Aspect注解中标注的是否为singleton类型,默认的切面类都是singleton类型
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// ---------找到增强类中的增强方法, 也就是那些标记 @Before @After 这些注解的方法---------
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
// 如果切面类是singleton类型,则将解析得到的Advisor进行缓存
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// 如果不是单例,则将factory放到缓存,以便再次获取时可以通过factory来解析
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// 如果@Aspect注解标注的beanName的Bean是单例,但切面实例化模型不是单例,则抛异常
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
// 将当前BeanFactory和切面bean封装为一个多例类型的Factory,同时对当前bean和factory进行缓存
MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
// 根据aspectName从缓存中获取Advisor集合
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
// 缓存获取到了,返回结果
advisors.addAll(cachedAdvisors);
}
else {
// 如果不存在于advisorsCache缓存,则代表存在于aspectFactoryCache中,可能是多例的情况,这时候不能bean,而要存beanFactory
// 从aspectFactoryCache中拿到缓存的factory,然后解析出Advisor,添加到结果中
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
c> getAdvisors() 解析切面类中的增强方法
【方法功能】:上面在buildAspectJAdvisors()
已经晒出出所有的AOP切面类了,然后就是遍历这些类,通过该方法,筛选里面的切面方法
- 获取切面类所有标注了AOP注解的方法
- 遍历处理方法
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 1.获取类型
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 2.获取beanName
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
// 3.验证
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
// 通过上面的英文可以看出将其进行封装,使用装饰器模式,保持每次获取到的都是同一个切面实例
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
// 获取所有的没有使用@Pointcut注解标注的方法,然后对其进行遍历
for (Method method : getAdvisorMethods(aspectClass)) {
// 判断当前方法是否标注有@Before,@After或@Around等注解,如果标注了,则将其封装为一个Advisor
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// 如果Advisor不为空,并且是需要延迟初始化的bean,则在第0位位置添加一个同步实例化增强器(用以保证增强使用之前的实例化)
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
// 判断属性上是否包含有@DeclareParents注解标注的需要新添加的属性,如果有,则将其封装为一个Advisor
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
d> getAdvisor() 普通增强器获取
【方法功能】:前面已经找到了切面类中的所有方法,接下来就是遍历每个方法,层层遍历
上面的getAdvisor()
获取到了切面类中的所有方法,然后调用该重载方法,负责对切点方法注解的获取,然后根据注解信息生成增强
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
// 校验
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 切点信息的获取
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 根据切点信息生成增强器
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
e> getPointcut() 切入信息的获取
【方法功能】:负责解析切面注解上的切入点
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 1.查找并返回给定方法的第一个AspectJ注解(@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut)
AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// 2.使用AspectJExpressionPointcut实例封装获取的信息
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
// 提取得到的注解中的表达式,
// 例如:@Around("execution(* com.joonwhee.open.aop.*.*(..))"),得到:execution(* com.joonwhee.open.aop.*.*(..))
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] {
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class};
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
// 从所有的切面注解遍历,找到该方法匹配的注解
for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {
AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
f> 根据切点信息生成增强器
> 创建增强器包装类并赋初始值
所有的增强都由Advisor
的实现类InstantiationModelAwarePointcutAdvisorImpl
统一封装的
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 实例化增强器
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
> 创建增强器对象
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
通过下面方法中的switch可以看到,Spring会根据不同的注解生成不同的增强器
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
// 根据不同的类创建
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
> 筛选该bean可以使用的增强器
a> findAdvisorsThatCanApply()
【方法描述】:遍历全部增强器,依次判断该bean可否应用
继续回到上面的方法中wrapIfNecessary() -> getAdvicesAndAdvisorsForBean() -> findEligibleAdvisors()
中,当我们获取了全部的增强以后,这个肯定需要缓存起来的,然后创建bean的时候,需要筛选出该bean可以使用的增强器
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
// 空的话直接返回
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
// 首先处理引介增强(@DeclareParents)用的比较少可以忽略
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
// 遍历所有增强器
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 判断是否可以应用
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
b> canApply() 判断该bean可否应用增强器
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
// 判断是否上面提到的引介增强,用的比较少
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
// 通常我们的Advisor都是PointcutAdvisor类型
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
这里面就是负责把切入点和方法进行匹配
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 判断目标bean是否与增强器上面的切点表达式是否匹配
// 也就是判断 @Pointcut(value = "execution(public int com.h3c.aop.bean.*.*(..))") 这个和目前bean是否匹配
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
// 判断如果当前Advisor所指代的方法的切点表达式如果是对任意方法都放行,则直接返回
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
// 获取目标类的所有接口
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
// 遍历目标类上的接口方法
for (Class<?> clazz : classes) {
//
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
// 使用matches判断能否作用于该方法上
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
3.执行逻辑图
上面介绍了如何获取增强器,那么在通过下面的图回顾一下:
三、根据增强器创建代理
1.Spring代理介绍
上面已经获取到了其增强器,然后继续回到wrapIfNecessary()
,接下来就是开始创建代理了,那么在看源码之前先把代理的知识聊一下
如果忘了最基础的如何创建代理请阅读《GoF设计模式》 之No.11代理模式》
那么接下来说一下Spring框架,Spring作为一个优秀的框架,提供了多种应用层面上代理的方式:ProxyFactoryBean、ProxyFactory、AspectJProxyFactory
注意:此处这里指的是Spring提供的应用层得方式,并不是指的底层实现方式。底层实现方式现在只有业界都熟悉的两种:JDK动态代理和CGLIB代理~
ProxyFactoryBean
是将我们的AOP和IOC
融合起来,ProxyFactory
则是只能通过代码硬编码进行编写 一般都是给spring自己使用。AspectJ
是目前大家最常用的集成AspectJ
和Spring
涉及的关键类说明
ProxyConfig
:为上面三个类提供配置属性
AdvisedSupport
:继承ProxyConfig,实现了Advised。封装了对通知(Advise)和通知器(Advisor)的操作
ProxyCreatorSupport
:继承AdvisedSupport,其帮助子类(上面三个类)创建JDK或者cglib的代理对象
1) ProxyFactoryBean
使用Spring提供的类org.springframework.aop.framework.ProxyFactoryBean
是创建AOP的最基本的方式,是比较麻烦的,需要实现特定的接口,并进行一些较为复杂的配置。
它是将Aop和IOC融合起来,所以它肯定是个Bean,然后我们可以自定义我们的代理实现逻辑,最终交给Spring容器管理即可。
public class ProxyFactoryBean extends ProxyCreatorSupport
implements FactoryBean<Object>, BeanClassLoaderAware, BeanFactoryAware {
【写个例子】
@Configuration
public class ProxyConfig {
// 目标类
@Bean
public HelloService helloService() {
return new HelloService();
}
// 增强类
@Bean
public LogMethodBeforeAdvice logMethodBeforeAdvice() {
return new LogMethodBeforeAdvice();
}
// 创建一个代理,注入IOC,从这里可以看到ProxyFactoryBean会与IOC融合起来
@Bean
public ProxyFactoryBean proxyFactoryBean(HelloService helloService) {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
// 设置目标对象
proxyFactoryBean.setTarget(helloService);
// 设置需要被代理的接口
proxyFactoryBean.setInterfaces(HelloInterface.class);
// 需要植入进目标对象的bean列表 此处需要注意:这些bean必须实现类 org.aopalliance.intercept.MethodInterceptor或 org.springframework.aop.Advisor的bean ,配置中的顺序对应调用的顺序
proxyFactoryBean.setInterceptorNames("logMethodBeforeAdvice");
return proxyFactoryBean;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ProxyConfig.class);
HelloInterface helloInterface = (HelloInterface) context.getBean("proxyFactoryBean");
helloInterface.hello();
}
}
interface HelloInterface {
void hello();
}
class HelloService implements HelloInterface {
@Override
public void hello() {
System.out.println("执行hello()-------");
}
}
class LogMethodBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("before-----------------");
}
}
2) ProxyFactory
它和Spring容器没啥关系,可议直接创建代理来使用:
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory(new HelloService());
// 添加两个Advise,一个匿名内部类表示
proxyFactory.addAdvice((AfterReturningAdvice) (returnValue, method, args1, target) ->
System.out.println("AfterReturningAdvice method=" + method.getName()));
proxyFactory.addAdvice(new LogMethodBeforeAdvice());
HelloInterface proxy = (HelloInterface) proxyFactory.getProxy();
proxy.hello();
}
// 输出
before-----------------
执行hello()-------
AfterReturningAdvice method=hello
很显然它代理的Bean都是new出来的,所以比如HelloServiceImpl
就不能和Spring IoC很好的结合了,所以一般都是Spring内部去使用。
public class ProxyFactory extends ProxyCreatorSupport {
// 它提供了丰富的构造函数~~~
public ProxyFactory() {
}
public ProxyFactory(Object target) {
setTarget(target);
setInterfaces(ClassUtils.getAllInterfaces(target));
}
public ProxyFactory(Class<?>... proxyInterfaces) {
setInterfaces(proxyInterfaces);
}
public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
addInterface(proxyInterface);
addAdvice(interceptor);
}
public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
addInterface(proxyInterface);
setTargetSource(targetSource);
}
// 创建代理的语句:调用父类ProxyCreatorSupport#createAopProxy 此处就不用再解释了
public Object getProxy() {
return createAopProxy().getProxy();
}
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
// 主义这是个静态方法,可以一步到位,代理指定的接口
public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {
return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
}
public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
}
// 注意:若调用此方法生成代理,就直接使用的是CGLIB的方式的
public static Object getProxy(TargetSource targetSource) {
if (targetSource.getTargetClass() == null) {
throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(targetSource);
proxyFactory.setProxyTargetClass(true);
return proxyFactory.getProxy();
}
}
3) AspectJProxyFactory
在低版本Spring中定义一个切面是比较麻烦的,需要实现特定的接口,并进行一些较为复杂的配置,低版本Spring AOP的配置是被批评最多的地方。Spring听取这方面的批评声音,并下决心彻底改变这一现状。在Spring2.0中,Spring AOP已经焕然一新,你可以使用@AspectJ注解非常容易的定义一个切面,不需要实现任何的接口
AspectJ是目前大家最常用的 起到集成AspectJ和Spring,也就是我们平时长谈的:自动代理模式。它整个代理的过程全部交给Spring内部去完成,无侵入。
我们只需要配置切面、通知、切点表达式就能自动的实现切入的效果,使用起来极其方便,对调用者可以说是非常透明化的。相信这也是为何当下最流行这种方式的原因~
2.源码分析
接下来就是继续看源码了,首先,下面看到的Aop代理源码,采用的ProxyFactory
,也就是上面介绍到的第2种,采用硬编码的方式
> createProxy() 创建代理工厂
// AbstractAutoProxyCreator
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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (proxyFactory.isProxyTargetClass()) {
if (Proxy.isProxyClass(beanClass)) {
Class[] var6 = beanClass.getInterfaces();
int var7 = var6.length;
for(int var8 = 0; var8 < var7; ++var8) {
Class<?> ifc = var6[var8];
proxyFactory.addInterface(ifc);
}
}
} else if (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
// 获取所有增强器(通知方法)
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
// 保存到proxyFactory
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
this.customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
ClassLoader classLoader = this.getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader)classLoader).getOriginalClassLoader();
}
// 获取代理
return proxyFactory.getProxy(classLoader);
}
> getProxy 获取代理对象
// ProxyFactory
public Object getProxy(@Nullable ClassLoader classLoader) {
// createAopProxy()调用的父类ProxyCreatorSupport
return createAopProxy().getProxy(classLoader);
}
> createAopProxy 创建AOP代理
// ProxyCreatorSupport
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
// DefaultAopProxyFactory
// 创建代理对象
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(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);
}
// 普通对象则使用cglib动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 存在接口, 则使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
> getProxy()
这里会获取代理对象,如果是采用的JDK动态代理,则执行到JdkDynamicAopProxy
中
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// 我们熟悉的代理创建
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
如果是采用的Cglib代理,则进入CglibAopProxy
中
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
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));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
s(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
“: Common causes of this problem include using a final class or a non-visible class”,
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException(“Unexpected AOP exception”, ex);
}
}