Spring源码解析-AOP
前言
AOP是我们使用Spring时较为常用的功能,今天让我们来看看其中的玄机
@EnableAspectJAutoProxy
项目中使用AOP的时候,都必须在某个类上标注@EnableAspectJAutoProxy,代表开启AOP,这个开启AOP是什么意思呢?
@Aspect
@Component
@Slf4j
@EnableAspectJAutoProxy
public class AspectTest {
}
点击进去EnableAspectJAutoProxy,会发现EnableAspectJAutoProxy import 了AspectJAutoProxyRegistrar类
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
在之前的Spring文章中,我曾写过,@Import这个注解可以引入三种类型的类
- ImportSelector类型
- ImportBeanDefinitionRegistrar类型
- 普通类
不管哪种类型,都是注册BeanDefinition的一种方式,此处Import的是ImportBeanDefinitionRegistrar,这个类注册了AnnotationAwareAspectJAutoProxyCreator这个BeanDefinition
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
看看AnnotationAwareAspectJAutoProxyCreator这个类的继承图,会发现它只是在原有Spring-AOP的基础上做了注解方面的扩展。需要特别注意的是,该类实现了BeanPostProcessor,对Spring源码比较熟悉的同学应该知道实现这个类意味着什么,说明AOP是在Spring原有Bean生命周期上加东西,并没有逃脱Spring的牢笼
一些基础知识
Advice与Advisor
我们经常会看到Advice、Advisor,他们有什么区别呢?
Advice是通知,Advisor是增强器,每个Advisor都会持有一个Advice
public interface Advisor {
Advice EMPTY_ADVICE = new Advice() {};
// 比如这个接口,可以获取Advisor持有的Advice
Advice getAdvice();
boolean isPerInstance();
}
AopInfrastructureBean
// Spring内部的这个接口没有任何实现,只是一个标记接口,如果Spring中的类实现了这个接口,就会被标记为Spring的基础设施类
// 不会被自动代理
public interface AopInfrastructureBean {
}
// 在AbstractAutoProxyCreator这个类中,有一个方法,判断某个类需不需要被代理
// 如果是Advice、Pointcut、Advisor、AopInfrastructureBean的子类,则不需要被代理
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
Pointcut
Pointcut作为Spring AOP最顶级的抽象,主要负责对系统相应Joinpoint的捕获,如果把Joinpoint比做数据,那么Pointcut就是查询条件,一个Pointcut可以对应多个Joinpoint。ClassFilter和MethodMatcher分别限定在不同级别上对于Joinpoint的匹配,ClassFilter是类级别,MethodMatcher是方法级别,使用AOP的同学应该都清楚,AOP主要支持方法级别的匹配,所以类级别的匹配功能较为简单
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
Pointcut TRUE = TruePointcut.INSTANCE;
}
public interface ClassFilter {
// 给定的类是否匹配
boolean matches(Class<?> clazz);
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
public interface MethodMatcher {
// 在这里有一个静态切入点和动态切入点的概念
// 静态切入点:只进行一次检测
// 动态切入点:每次切入都检测
boolean matches(Method method, Class<?> targetClass);
// 判断静态切入点和动态切入点的标志,return true表示动态
boolean isRuntime();
boolean matches(Method method, Class<?> targetClass, Object... args);
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
IntroductionAdvisor
为AOP提供类级别的拦截
public interface IntroductionAdvisor extends Advisor, IntroductionInfo {
ClassFilter getClassFilter();
void validateInterfaces() throws IllegalArgumentException;
}
public interface IntroductionInfo {
// 这个接口可以定义AOP适用的类,不适用的类,可以不进行AOP拦截
Class<?>[] getInterfaces();
}
PointcutAdvisor
为AOP提供方法级别的拦截
public interface PointcutAdvisor extends Advisor {
Pointcut getPointcut();
}
单纯看以上几个类,可能会很懵,下面是AOP过程中获取拦截器链的代码,结合这些代码感受一下AOP是如何对Advisor进行筛选的
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {
// 如果advisor是PointcutAdvisor的实例
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 如果是预先筛选过或者advisor适用于目标类
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 进行方法级别的筛选
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// 如果是动态切入点
if (mm.isRuntime()) {
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
// 如果advisor是IntroductionAdvisor的实例
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;
}
AdvisorAdapter
Advisor适配器,适配器这种类一般都是连接某两个类之间的桥梁,AdvisorAdapter则是连接Advisor与MethodInterceptor之间的桥梁,动态代理中,要执行指定的方法前,会执行一系列的拦截器,这些拦截器的单位是MethodInterceptor
public interface AdvisorAdapter {
// 这个适配器是否支持这个Advice
boolean supportsAdvice(Advice advice);
// 将一个Advisor转换成MethodInterceptor
MethodInterceptor getInterceptor(Advisor advisor);
}
我们简单地看一个类,感受一个这个适配器是如何进行转换的
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
// 在构造器中就构建好了AdvisorAdapter的几个实现类
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
// 如何Advice本身就是MethodInterceptor,不需要进行转换
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 遍历adapters,先看这个AdvisorAdapter是否支持适配Advice,如果支持,则转换成MethodInterceptor
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
源码解析
上文讲过,AnnotationAwareAspectJAutoProxyCreator继承AbstractAutoProxyCreator且实现了BeanPostProcessor,在AbstractAutoProxyCreator类中,有两个方法是比较重要的,分别是postProcessBeforeInstantiation和postProcessAfterInitialization,先看看postProcessBeforeInstantiation
postProcessBeforeInstantiation
此方法主要是拦截一些不需要代理的类
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
// 这里有两重判断
// 1.如果beanName不为空
// 2.如果这个bean不存在于targetSourcedBeans这个Map缓存中(当bean有自定义的TargetSource,会在这个方法中创建代理
// 并且放到Map中
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
// 如果bean存在于advisedBeans这个Map缓存中,直接返回
// advisedBeans这个Map其实就是存在了哪些bean是不需要被代理的
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// isInfrastructureClass 这个方法会判断哪些bean是不需要被代理,shouldSkip 这个方法会判断该类是否需要被跳过
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// 如果我们有自定义TargetSource,则在此处获取,并且创建代理
// 一般不会自定义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这个方法,这个方法非常重要,在这个方法中,AOP所需要的Advisor都已经解析完毕
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 找到候选的Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
@Override
protected List<Advisor> findCandidateAdvisors() {
// 根据规则找出实现了Advisor接口的bean
List<Advisor> advisors = super.findCandidateAdvisors();
// 找出标注了@Aspect注解的bean
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// 获取当前BeanFactory中所有实现了Advisor接口的bean的名称
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
// 对实现Advisor接口的bean的名称进行遍历
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
// 提供了一个hook方法,可做适当扩展排除此name
if (isEligibleBean(name)) {
// 如果当前bean还在创建过程中,忽略
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 将其放在结果中返回
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
// 保存解析处理出来的Advisor对象
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 此处传入的是Object对象,代表获取容器中所有的组件的名称,十分消耗性能
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 遍历所有名称
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// 根据beanName获取Class
Class<?> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 判断该Class是否为切面@Aspect
if (this.advisorFactory.isAspect(beanType)) {
// 切面类则加入到缓存中
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 获取Advisor
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);
}
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);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
// aspectNames不为空,说明之前已经解析过了,不需要重复解析,直接获取缓存中的数据
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;
}
详细看看getAdvisors方法
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
// 获取标记为@Aspect的Class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
// 获取标记为@Aspect的名称
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
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)) {
// 解析切面中的方法
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 instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
// 当前的切点表达式
this.declaredPointcut = declaredPointcut;
// 切面的Class
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()) {
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 构造Advice对象
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
@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;
// 根据注解生成相应的Advice实现类
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);
}
// 配置该Advice
// 设置切面名称
springAdvice.setAspectName(aspectName);
// 设置切面的执行优先级
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
// 设置方法参数
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
postProcessAfterInitialization
经过postProcessBeforeInstantiation的处理,所有不需要被代理的类都已经被屏蔽了,Advisor也已经解析完毕,万事具备,只差生成代理对象了
@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;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果是基础设施类,或是应该跳过的类,则不应该生成代理,直接返回bean
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 如果specificInterceptors不为空,则创建对应的代理对象
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;
}
@Override
@Nullable
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();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 找到IOC容器中所有实现了Advisor接口的bean
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 判断找到的Advisor接口能否应用到当前的bean上
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 对Advisor进行排序
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 这里有一个比较关键的判断,config.isProxyTargetClass() 默认为false
// 假如为true,则表示强制使用cglib代理
// 所以有些面试官会问,哪些类会用cglib代理,哪些类会用jdk动态代理,我们一般回答类实现了接口会用jdk动态代理
// 没有接口会用cglib代理,其实回答得并不是很全面
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);
}
}
@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);
}
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
// 此处有两个判断
// 1.advisors是否为空,前面我们讲过,advisor是advice的容器,如果advisor为空,表示没有对应的切面
// 2,targetSource是否为空,表示代理的来源不能为空
// 这两个判断的意思是,创建代理时,如果没有类的来源或者没有对应的切面,没有创建代理的意义
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
// 获取所有的代理接口
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 判断equal和hashCode方法是否被重写
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
// 这个方法比较有意思,我们都知道equal和hashCode方法会经常被集合框架用到,用于判断key是否重复,是一个比较高频的操作
// 所以AOP会特别地缓存下来此接口是否重写了equal和hashCode方法
private void findDefinedEqualsAndHashCodeMethods(Class<?>[] proxiedInterfaces) {
for (Class<?> proxiedInterface : proxiedInterfaces) {
Method[] methods = proxiedInterface.getDeclaredMethods();
for (Method method : methods) {
// 判断equal是否被重写
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
// 判断hashCode方法是否被重写
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
// 若是两个方法都被重写,就不继续往下找了
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
方法调用实现拦截
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
// 获取目标对象
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 如果是equal方法不需要代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
// 如果是hashCode方法不需要代理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
.....
Object retVal;
// 将代理对象暴露在线程变量中
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 如果拦截器链为空,则直接调用指定方法
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 如果拦截器链不为空,则使用到了责任链设计模式
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 执行拦截器链
retVal = invocation.proceed();
}
// 获取方法返回值类型
Class<?> returnType = method.getReturnType();
// 如果返回值为this,则将代理对象proxy返回
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
// 如果返回值类型为基础类型,比如int,但是retVal又为null,抛出异常
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
@Override
@Nullable
public Object proceed() throws Throwable {
// 下标从-1开始,直到最后一个拦截器,执行目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取拦截器前,先++
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
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 {
return proceed();
}
}
else {
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
参考资料
极客时间
转载自:https://juejin.cn/post/7079719785772089380