如果我们自己实现一个AOP?
什么时候生成代理对象呢?
肯定是普通的 bean 在初始化阶段,被 BeanPostProcessor 影响后,在 postProcessAfterInitialization
方法中生成代理对象吧!
解析切入点表达式的时机
在 AOP 核心后置处理器的初始化阶段
,解析容器中的所有切面类中的切入点表达式。
通知织入的方式
底层实现是通过动态代理。动态代理分为jdk动态代理,Cglib动态代理。条件选择合适的动态代理进行通知织入。
总体思路就是:
1.通过后置处理器,拦截切面类,筛选出所有切入点表达式。
2.bean初始化的时候调用后置处理器,匹配bean是否符合切入点表达式。
3.对于符合的,找到对应方法,通过动态代理织入增强的逻辑,返回代理的对象。
AOP代理的底层核心后置处理器
这个要从我们配置的开启AOP的注解看起。—@EnableAspectJAutoProxy
@EnableAspectJAutoProxy
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
可以发现,里面有个@Import
注解,导入了一个AspectJAutoProxyRegistrar
。
AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册核心后置处理器的动作
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//解析@EnableAspectJAutoProxy的属性并配置
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
可以发现这个类实现ImportBeanDefinitionRegistrar
接口。向IOC容器注入BeanDefinition:
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
可以发现,已经指定要注册的类型是:AnnotationAwareAspectJAutoProxyCreator
。
进入下面的注册方法:
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
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 {
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;
}
}
AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
它兼顾 AspectJ 风格的切面声明,以及 SpringFramework 原生的 AOP 编程。
AnnotationAwareAspectJAutoProxyCreator实现的几个重要的接口:
1.BeanPostProcessor
。通过调用 postProcessAfterInitialization生成代理对象。
2.InstantiationAwareBeanPostProcessor
:连接bean的正常的doCreateBean创建流程。
3.SmartInstantiationAwareBeanPostProcessor
:提前预测 bean 的类型、暴露 bean 的引用。
4.AopInfrastructureBean
:实现了该接口的 bean 永远不会被代理(防止套娃)。
什么时候创建这个后置处理器:AnnotationAwareAspectJAutoProxyCreator
在Bean的实例化阶段,调用AbstractApplicationContext#refresh的registerBeanPostProcessors(beanFactory);
方法。注册,初始化BeanPostProcessor后置处理器。
由于AnnotationAwareAspectJAutoProxyCreator实现Ordered接口,它会提前与普通的BeanPostProcessor创建。
AnnotationAwareAspectJAutoProxyCreator什么时候起作用
当这个后置处理器被创建初始化后,所有的bean实例都应该被它干预。
bean的创建流程:
在doCreatBean中进行创建对象,属性赋值,组件注入,初始化的流程。
当初始化执行完毕,就该BeanPostProcessor 后置处理器的postProcessAfterIntialization
方法。
AnnotationAwareAspectJAutoProxyCreator#postProcessBeforeInstantiation
//AbstractAutoProxyCreator#postProcessBeforeInstantiation
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
// 决定是否要提前增强当前bean
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 被增强过的bean不会再次被增强
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 基础类型的bean不会被提前增强、被跳过的bean不会被提前增强
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 原型bean的额外处理:TargetSource
// 此处的设计与自定义TargetSource相关,单实例bean必定返回null
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;
}
isInfrastructureClass
基础类型的bean。
protected boolean isInfrastructureClass(Class<?> beanClass) {
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
// logger ......
return retVal;
}
其实就是切面,切入点,增强器等对象。这些作为底层的组成成员,不应该参与具体的增强器对象中。
shouldSkip
// AspectJAwareAdvisorAutoProxyCreator
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 加载增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
// 逐个匹配,如果发现当前bean的名称与增强器的名称一致,则认为
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
// AbstractAutoProxyCreator
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 检查beanName代表的是不是原始对象(以.ORIGINAL结尾)
return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}
1.当前bean是不是有增强器名称一样的。
一般情况,我们构造的 bean 根本就不可能带有 .ORIGINAL 的后缀,所以这个地方相当于判断当前创建的 bean 是否名称与增强器撞车。
2.当前bean是不是一个还没有经过任何代理的原始对象。
一个Advisor = 一个pointcut + 一个advice。
切面类(Aspect)中定义的通知方法,方法体 + 方法上的通知注解就可以看做是一个Advisor增强器。
3.AOP 的代理其实不是代理的目标对象本身
,而是目标对象包装后的 TargetSource
对象。
AOP切面类的收集findCandidateAdvisors
findCandidateAdvisors方法就是解析切面类,构造增强器的过程。
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 根据父类的规则添加所有找到的Spring原生的增强器
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 解析BeanFactory中所有的AspectJ切面,并构造增强器
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
核心步骤:
1.找到Spring框架原生的AOP增强器
2.解析切面类,并构造增强器
super.findCandidateAdvisors
private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
可以发现它通过BeanFactoryAdvisorRetrievalHelper
的方法findAdvisorBeans
来查找原生的AOP增强器。
进入findAdvisorBeans方法:
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
// 确定增强器bean名称的列表(如果尚未缓存)
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
// 不要在这里初始化FactoryBeans:
// 我们需要保留所有未初始化的常规bean,以使自动代理创建者对其应用
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
// 如果当前IOC容器中没有任何增强器类型的bean,直接返回
if (advisorNames.length == 0) {
return new ArrayList<>();
}
// ......
就是将IOC容器中所有类型是Advisor的实现类都找出来。
BeanFactoryUtils 的 beanNamesForTypeIncludingAncestors
方法,底层是用的 getBeanNamesForType
方法去找 bean 的名称。
如果没有找到,直接返回。
如果找到有Advisor的实现类。进行初始化原生增强器。
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
// logger ......
}
else {
try {
//初始化原生的增强器
advisors.add(this.beanFactory.getBean(name, Advisor.class));
} // catch ......
}
}
}
return advisors;
}
aspectJAdvisorsBuilder.buildAspectJAdvisors
核心就是:将 Aspect 切面类,转换为一个一个的增强器。
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 获取IOC容器中的所有bean
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
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,因为在这种情况下,IOC容器会缓存它们,但不会被织入增强器
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// ......
核心逻辑:
将IOC容器中所有的beanNames都取出来,获取每个bean的Class。
接下来进行Aspect类型的切面解析。
// ......
//isAspect方法判断beanType是否是@Aspect注解标注的类
if (this.advisorFactory.isAspect(beanType)) {
// 当前解析bean的所属类型是一个切面类
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 下面是单实例切面bean会走的流程
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 解析生成增强器
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
// ......
isAspect方法判断是否是@Aspect标注的类。
advisorFactroy.getAdvisors构造增强器。
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// Aspect切面类的Class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
// 再次校验一下切面类上是不是标注了@Aspect注解
validate(aspectClass);
// 此处利用Decorator装饰者模式,目的是保证Advisor增强器不会被多次实例化
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
// 逐个解析通知方法,并封装为增强器
for (Method method : getAdvisorMethods(aspectClass)) {
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.
// 通过在装饰者内部的开始加入SyntheticInstantiationAdvisor增强器,达到延迟初始化切面bean的目的
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
// 对@DeclareParent注解功能的支持(AspectJ的引介)
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
切面类中通知方法的收集getAdvisorMethods
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
if (methods.size() > 1) {
methods.sort(METHOD_COMPARATOR);
}
return methods;
}
核心逻辑:将切面类中,除了@Pointcut标注的通用切入点表达式外,其他的方法都提取出来。并按照Unicode编码排序。
创建增强器getAdvisor
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);
}
创建增强器通过new InstantiationModelAwarePointcutAdvisorImpl。
构造函数出入一下几个参数:
1.expressionPointcut:切入点表达式
2.candidateAdviceMethod:通知方法本体
3.this:当前的ReflectiveAspectJAdvisorFactory
4.aspectInstanceFactory:装饰者 MetadataAwareAspectInstanceFactory
增强器的结构就是:一个切入点表达式 + 一个通知方法。
原型切面bean的处理
// ......
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
// 解析Aspect切面类,构造增强器
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
// ......
它的核心解析动作依然是 advisorFactory.getAdvisors
方法,只是这里面不会再用到 advisorsCache
这个缓存区了,这也说明原型切面 bean 的解析是多次执行的。
增强器汇总
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization
前面的拦截结束,在起作用就到了后面bean初始化之后调用postProcessAfterInitialization
方法。
//AbstractAutoProxyCreator#postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
//如果是工厂bean,返回&+beanName,否则返回beanName。如果beanName为空,bean.getClass对象。
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 核心:构造代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
核心方法:wrapIfNecessary
。如果有必要的话,给这个对象包装生成代理对象。
wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 判断决定是否是不会被增强的 bean
if (StringUtils.hasLength(beanName) && 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);
// 创建代理对象的动作
// 注意此处它创建了一个SingletonTargetSource,将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;
}
核心步骤:
1.判断当前bean是否是不被增强的bean。
2.根据当前bean去匹配增强器。
3.如果增前期不为空,创建代理对象
getAdvicesAndAdvisorsForBean
根据当前bean去匹配增强器
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//找到合适的增强器
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
核心逻辑是findEligibleAdvisors
:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取所有增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 筛选出可以切入当前bean的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 添加额外的增强器
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 增强器排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
取出所有的增强器,筛选出可以切入当前bean的增强器,添加额外的增强器,进行排序。
findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
将Spring框架原生的增强器和AspectJ形式封装的增强器都拿出来。
findAdvisorsThatCanApply
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
通过AopUtils的findAdvisorsThatCanApply方法过滤出匹配的增强器。
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
// 先匹配引介增强器
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;
}
前面是针对引介通知的增强器作筛选,后面是普通的方法通知封装的增强器。
一下是普通的方法通知匹配:
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
// 对于引介增强器,它会直接强转,使用类级别的过滤器去匹配
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
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.
// SpringFramework也不知道咋搞了,于是就直接让它可以匹配
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 类不匹配直接返回
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
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) {
// 逐个判断每个方法是否能被当前切入点表达式切入,切入则立即返回true
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
最终eligibleAdvisors集合中存放的就是匹配到的增强器。
extendAdvisors
dug会发现,过了这个方法后eligibleAdvisors集合中会多了一个增强器。
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}
// AspectJProxyUtils
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
// Don't add advisors to an empty list; may indicate that proxying is just not required
if (!advisors.isEmpty()) {
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
// Be careful not to get the Advice without a guard, as this might eagerly
// instantiate a non-singleton AspectJ aspect...
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
break;
}
}
// 发现有AspectJ包装的增强器,则添加一个ExposeInvocationInterceptor
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
return true;
}
}
return false;
}
判断当前可用的增强器中有没有 AspectJ 类型的,如果有的话,那就在整个增强器的列表的最前面,添加一个 ExposeInvocationInterceptor.ADVISOR 。
ADVISOR如下:
public static final ExposeInvocationInterceptor INSTANCE = new ExposeInvocationInterceptor();
public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
@Override
public String toString() {
return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
}
};
ExposeInvocationInterceptor如下:
private static final ThreadLocal<MethodInvocation> invocation =
new NamedThreadLocal<>("Current AOP method invocation");
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
翻开源码的核心 invoke 方法,发现它在向当前线程的 ThreadLocal 中放入了当前正在执行的代理对象的方法执行包装。
每次都在增强器链的第一个执行,并且放入到线程变量ThreadLocal中。它可以让后面的增强器都拿到当前正在执行的MethodInvocation。
createProxy
所有的增强器也就都准备好了,接下来就是创建代理对象的部分了。
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 记录被代理bean的原始类型
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 代理工厂的初始化
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 根据AOP的设计,决定是否强制使用Cglib
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
// Cglib动态代理直接记录被代理bean的所属类即可
proxyFactory.setProxyTargetClass(true);
}
else {
// 解析被代理bean所属类的所有实现的接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 1.2.1 构造整合所有增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 1.2.2 创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
核心逻辑:
1.收集整理要织入到目标对象的通知增强器
2.创建代理对象
buildAdvisors
构建整合所有增强器:
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
// 这个地方是适配Spring原生AOP的MethodInterceptor,感兴趣的小伙伴可自行研究
Advisor[] commonInterceptors = resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
allInterceptors.addAll(Arrays.asList(specificInterceptors));
// 组合原生的方法拦截器,共同作为AOP的通知织入
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
// logger ......
Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// 此处有一个原生AOP的适配动作
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
以上整合spring框架原生的AOP。
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// Advisor增强器可以直接返回
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 不支持非Advice的类型
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
// MethodInterceptor的支持
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
// AdvisorAdapter的支持
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
这个方法的含义:将可以支持转换/包装为Advisor类型的对象适配成Advisor。所以方法返回的一定是Advisor。
proxyFactory.getProxy
接下来开始真正创建代理对象。
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
createAopProxy
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
private void activate() {
this.active = true;
for (AdvisedSupportListener listener : this.listeners) {
listener.activated(this);
}
}
getAopProxyFactory 方法返回的是当前 ProxyCreatorSupport 的成员 aopProxyFactory ,借助 Debug 可以发现它的类型是 DefaultAopProxyFactory
。
进入到它的 createAopProxy 方法中:
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.");
}
// 如果要代理的本身就是接口,或者已经是被jdk动态代理了的代理对象
// 则使用jdk动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用Cglib动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
创建完AopPorxy后,下面就是创建代理对象的动作:
AopProxy#getProxy
一下进入JdkDynamicAopProxy的getProxy方法。
public Object getProxy(@Nullable ClassLoader classLoader) {
// logger ......
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// jdk动态代理的API
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
Proxy.newProxyInstance就是我们熟悉的代理对象的创建。
以下是Cglib的getProxy方法:
// ......
// 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);
// ......
TargetSource
AOP 的代理其实不是代理的目标对象本身,而是目标对象包装后的 TargetSource 对象。为了统一处理。
TargetSource 可以看做是目标对象 Target 的一个包装、容器,原本代理对象要执行 method.invoke(target, args) 这样的逻辑时,本来要拿到的是目标对象,但被 TargetSource 包装之后,就只能调用 method.invoke(targetSource.getTarget(), args) 这样的形式了。
public interface TargetSource extends TargetClassAware {
Class<?> getTargetClass();
boolean isStatic();
Object getTarget() throws Exception;
void releaseTarget(Object target) throws Exception;
}
SpringFramework中提供的TargetSource
1.SingletonTargetSource
:每次 getTarget 都返回同一个目标对象 bean (与直接代理 target 无任何区别)
2.PrototypeTargetSource
:每次 getTarget 都会从 BeanFactory 中创建一个全新的 bean (被它包装的 bean 必须为原型 bean )
3.CommonsPool2TargetSource
:内部维护了一个对象池,每次 getTarget 时从对象池中取(底层使用 apache 的 ObjectPool )
4.ThreadLocalTargetSource
:每次 getTarget 都会从它所处的线程中取目标对象(由于每个线程都有一个 TargetSource ,所以被它包装的 bean 也必须是原型 bean )
5.HotSwappableTargetSource
:内部维护了一个可以热替换的目标对象引用,每次 getTarget 的时候都返回它(它提供了一个线程安全的 swap 方法,以热替换 TargetSource 中被代理的目标对象)