在前面我们分析过IOC的大致流程,这期就带大家来分析Spring中另外一大特性AOP的实现原理。建议阅读本文前,懂得IOC的原理,AOP的使用以及基础的概念问题,因为AOP的实现是基于IOC之上的。
在学习AOP的时候,大家或多或少都听过AOP的原理是动态代理,但是大家有想过动态代理的前提是什么吗?不管是JDK还是CGlib代理,你都要给代理类传入被代理的对象,那说明这时候目标对象已经被创建出来了。把这一点带入到IOC的流程,大致可以猜到,AOP的实现一定是在bean被实例化之后。那么在bean的生命周期里,还能对bean进行一些操作的流程是什么呢?那就是BeanPostProcessor的子类可以完成了。想清楚了这一点后,我们就可以去找BeanPostProcessor的子类,看看哪一个和AOP有关。在这里还是展示一下是什么找到具体的实现类吧。
使用注解开启AOP功能的话,需要加上@EnableAspectJAutoProxy注解,跟进注解里面看
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//自动代理注册器,跟进去
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
#AspectJAutoProxyRegistrar
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//继续跟
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//......
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
//可以看到注册了一个AnnotationAwareAspectJAutoProxyCreator类型的bean
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
我们来看看AnnotationAwareAspectJAutoProxyCreator的继承体系
说明它就是我们要找的BeanPostProcessor了,而我们要分析的方法是在它的基类AbstractAutoProxyCreator里面,我们还是先看看IOC里bean的生命周期吧。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//......
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//BeanPostProcessor的postProcessBeforeInitialization回调
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//init-method回调
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//BeanPostProcessor的postProcessAfterInitialization回调
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
//返回包装Bean实例
return wrappedBean;
}
对IOC熟悉的朋友,应该都知道这个方法,在这里处理了BeanPostProcessor的回调方法和init-method。对于每个单例bean初始化都要经过一些处理器的回调,而AOP的实现就从这开始。
#AbstractAutoProxyCreator
//bean:初始化完成的bean实例
//beanName:bean的名称
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
//防止重复代理某个bean
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//AOP的开始
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//TargetSource场景,有兴趣可以自行了解,会在当前类的postProcessBeforeInstantiation中操作
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//isInfrastructureClass()判断是否为基础框架的类型
//shouldSkip() 判断beanName是否以.ORIGINAL结尾
//是这两种之一都不能被增强
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//查找适合当前bean的Class的通知
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//DO_NOT_PROXY==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;
}
//说明该bean不需要被增强,直接返回原实例
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
到这可以看出,经过AbstractAutoProxyCreator的postProcessAfterInitialization()方法后,需要被代理的bean最终会返回代理对象放入容器中。接下来就该分析Spring如何将我们配置的通知方法给解析出来,并如何创建代理对象的。
总体分为两个方法,一个是获取通知getAdvicesAndAdvisorsForBean(),一个是创建代理对象createProxy(),下面分别来看。
getAdvicesAndAdvisorsForBean()查找适合当前bean的增强通知
#AbstractAdvisorAutoProxyCreator
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//获取合适当前bean类型的通知
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
//为空返回null
return DO_NOT_PROXY;
}
//转成数据返回
return advisors.toArray();
}
#AbstractAdvisorAutoProxyCreator
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//获取当前容器内所有可以使用的Advisor,此方法在AnnotationAwareAspectJAutoProxyCreator进行了重写
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//将上面获取到的Advisor进行筛选,选出合适当前bean类型的Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//会在index==0 的位置加入一个类型为ExposeInvocationInterceptor的Advisor
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//将所有的通知进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
//返回匹配成功的通知集合
return eligibleAdvisors;
}
这个方法已经分析了内部方法的具体作用,因为调用链复杂,有需要的朋友可以选看,没有需求的朋友可以跳过这一部分,理解好这几个方法的作用,直接去看创建代理对象的过程。
findCandidateAdvisors()查找所有的通知
#AnnotationAwareAspectJAutoProxyCreator
@Override
protected List<Advisor> findCandidateAdvisors() {
//以下方法会从两种方式解析出Advisor
//1.获取通过bean配置的Advisor的bean实例
//这里最终调用到了#BeanFactoryAdvisorRetrievalHelper的findAdvisorBeans()
List<Advisor> advisors = super.findCandidateAdvisors();
//2.提取@Aspect注解类里面定义的Advisor信息
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
//1.获取通过bean配置的Advisor的bean实例
#BeanFactoryAdvisorRetrievalHelper
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
//查询出所有通过bean配置的是Advisor的子类的beanName
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
//遍历beanName
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
//从容器中拿出Advisor的实例
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
//......
}
}
}
}
//返回所有的Advisor
return advisors;
}
//2.提取@Aspect注解类里面定义的Advisor信息
#BeanFactoryAspectJAdvisorsBuilder
public List<Advisor> buildAspectJAdvisors() {
//获取缓存
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
//保存通过@Aspect注解定义的Advisor
List<Advisor> advisors = new LinkedList<Advisor>();
//保存带有@Aspect注解的类的beanName
aspectNames = new LinkedList<String>();
//获取容器内所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍历所有beanName
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//查询当前类型,父类,父类的父类...是否有@Aspect注解,有就说明当前类型是Aspect
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//使用工厂模式管理Aspect元数据,关联@Aspect注解的实例对象
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//获取@Aspect类中的Advisor信息,跟进去
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
//添加当前@Aspect注解类里所有的Advisor
advisors.addAll(classAdvisors);
}
else {
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));
}
}
}
//将刚刚循环处理后的@Aspect类的beanName缓存,表示该类已经提取过Advisor了
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
//从缓存中获取
List<Advisor> advisors = new LinkedList<Advisor>();
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;
}
#ReflectiveAspectJAdvisorFactory
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//获取@Aspect的Class
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//获取@Aspect的beanName
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new LinkedList<Advisor>();
//getAdvisorMethods()会获取出来@Before @After @Around @AfterReturning @AfterThrowing 这些方法
//不包括@PointCut
for (Method method : getAdvisorMethods(aspectClass)) {
//将当前方法包装成为Advisor,跟进去
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
//......
//返回当前@Aspect注解类里面的所有Advisor
return advisors;
}
#ReflectiveAspectJAdvisorFactory
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取切入点信息,candidateAdviceMethod就是@Aspect类里面的增强方法,从方法的注解上解析出切入点
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
//说明无法创建出对应的Advisor
if (expressionPointcut == null) {
return null;
}
//将方法包装成InstantiationModelAwarePointcutAdvisorImpl类型的实例
//expressionPointcut:切点表达式
//candidateAdviceMethod:增强方法
//this:构建Advisor的工厂,记住这个
//跟进去
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
#InstantiationModelAwarePointcutAdvisorImpl
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//一系列赋值操作
//......
//将ReflectiveAspectJAdvisorFactory的实例赋值给aspectJAdvisorFactory
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
//......
}
else {
//处理单实例的Aspect
this.pointcut = this.declaredPointcut;
this.lazy = false;
//进这个方法
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
#InstantiationModelAwarePointcutAdvisorImpl
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
//通过aspectJAdvisorFactory调用getAdvice,aspectJAdvisorFactory就是ReflectiveAspectJAdvisorFactory
//继续进去
return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
#ReflectiveAspectJAdvisorFactory
//在这个方法里,终于可以看到将@Aspect里面的增强方法包装成Advisor了
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取当前增强方法所属的@Aspect的Class
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//获取当前增强方法上定义的注解信息
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
//......
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
//前置通知
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;
//环绕通知
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//切点无法生成Advisor
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
//返回当前方法包装后的Advisor
return springAdvice;
}
到这里整个调用链返回(#AbstractAdvisorAutoProxyCreator的findEligibleAdvisors()方法),目前还只是将容器内所有的Advisor创建了出来,下一步就是筛选出适合当前bean的Advisor。
findAdvisorsThatCanApply()筛选出适合当前bean的通知
#AbstractAdvisorAutoProxyCreator
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
//candidateAdvisors:包含所有的Advisor
//clazz:当前bean的Class
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) {
continue;
}
//true,说明当前advisor匹配clazz
if (canApply(candidate, clazz, hasIntroductions)) {
//添加advisor
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);
}
//PointcutAdvisor是Advisor的子接口
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//继续跟
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//判断切入点是否匹配当前Class
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//获取方法匹配器
MethodMatcher methodMatcher = pc.getMethodMatcher();
//TRUEMethodMatcher类型的匹配器匹配所有方法
if (methodMatcher == MethodMatcher.TRUE) {
return true;
}
//......
//保存当前对象的Class,自身实现的接口,父类,父类的父类..实现的接口
Set<Class<?>> classes = new LinkedHashSet<>();
//确保targetClass没有被代理过,是原生的Class
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
//添加接口
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
//遍历所有Class,检查所有方法是否会被方法匹配器匹配
//只要有一个方法匹配成功,就说明当前bean需要被增强,返回true
for (Class<?> clazz : classes) {
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;
}
到这一步,适合当前bean的所有Advisor也被筛选出来了,我们再回到主分支里。
#AbstractAdvisorAutoProxyCreator
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//获取当前容器内所有可以使用的Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//将上面获取到的Advisor进行筛选,选出合适当前bean类型的Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//会在index==0 的位置加入一个类型ExposeInvocationInterceptor的Advisor
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//将所有的通知进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
//返回匹配成功的通知集合
return eligibleAdvisors;
}
费了这么大的力气,才只是把容器内所有适合当前bean的Advisor给筛选出来并返回,接下来就是通过这些Advisor进行创建代理的过程了。
createProxy()创建代理对象
还记得我们从哪来的吗?我们是从#AbstractAutoProxyCreator的postProcessAfterInitialization()方法调用进来的,最后会到这个方法里面来。
#AbstractAutoProxyCreator
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//......
//查找适合当前bean的Class的通知
//上面所有流程都是从这个方法调用开始的
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//DO_NOT_PROXY==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;
}
//说明该bean不需要被增强,直接返回原实例
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
接下来就去看Spring是如何创建代理对象的
#AbstractAutoProxyCreator
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//创建代理对象的工厂
ProxyFactory proxyFactory = new ProxyFactory();
//复制一些信息到proxyFactory,内部就是赋值一些相关属性
proxyFactory.copyFrom(this);
//ProxyTargetClass是AOP的配置属性,为true说明使用CGlib进行代理,默认false
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//specificInterceptors:就是前面创建出来并且适合当前bean的Advisor
//buildAdvisors()内部提供添加了用户自定义的公共Advisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
//将Advisor加入到proxyFactory
proxyFactory.addAdvisor(advisor);
}
//将目标对象加入到proxyFactory
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
//表示传递给proxyFactory的这些Advisor做过基础匹配,classFilter匹配
proxyFactory.setPreFiltered(true);
}
//proxyFactory创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
#ProxyFactory
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
#ProxyCreatorSupport
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//getAopProxyFactory()就是proxyFactory
//看createAopProxy()
return getAopProxyFactory().createAopProxy(this);
}
#DefaultAopProxyFactory
//在这里可以看到Spring是如何选取JDK还是CGlib进行动态代理的
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//config.isProxyTargetClass()对应ProxyTargetClass配置
//hasNoUserSuppliedProxyInterfaces(config)判断被代理对象是否有实现接口
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.");
}
//判断被代理对象的Class是否为接口,或者是否已经是被代理过的类型
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
//只能使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
//使用CGlib动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
//JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
到这里我们可以知道了proxyFactory.getProxy()就是通过JdkDynamicAopProxy或者ObjenesisCglibAopProxy调用的getProxy()。本文只分析JDK的动态代理过程,所以我们去看看JdkDynamicAopProxy的源码。
JdkDynamicAopProxy源码分析
首先看看这个类继承的接口
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable
其中有个接口是不是很熟悉?InvocationHandler,就是jdk动态代理的关键,那么肯定会重写invoke方法,所以这个类我们重点分析getProxy和invoke就行。
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//获取需要代理的接口数组
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//查找当前所有的需要代理的接口,看是否有equals和hashcode方法,有就打个标记
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//返回代理类对象
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
有写过jdk动态代理demo的朋友肯定很熟悉了,就不做过多分析,直接看invoke方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//用来驱动Advisor的执行链,后面分析
MethodInvocation invocation;
Object oldProxy = null;
boolean setProxyContext = false;
//获取ProxyFactory内部的目标对象
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
try {
//说明代理类实现的接口里面没有定义equals,并且当前method是equals的话,就使用JdkDynamicAopProxy提供的equals
//就是getProxy()里打的标记
//下面同理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
//方法返回值
Object retVal;
//是否需要将代理对象暴露到AOP上下文
if (this.advised.exposeProxy) {
//处理特殊情况,比如一个对象有A和B方法都需要增强,但是A内部还调用了B
//如果不将代理对象暴露出来,那么增强A调用的还是目标对象的B,B是没有增强的
//所以暴露代理对象后,增强A就能调用到代理对象的增强B了
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//真正的目标对象
target = targetSource.getTarget();
if (target != null) {
//获取目标对象的Class
targetClass = target.getClass();
}
//查找适合当前方法的所有方法拦截器,在此处会将Advisor转换成对应的方法拦截器
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果没有拦截器
if (chain.isEmpty()) {
//说明当前method不需要被增强
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//等同于 method.invoke
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
//说明method需要增强
//ReflectiveMethodInvocation核心,将代理对象,目标对象,当前方法,拦截器链都传入了
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//procced()开启拦截器调用链路
retVal = invocation.proceed();
}
//方法返回值类型
Class<?> returnType = method.getReturnType();
//如果method返回值类型是目标对象
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
//在此处进行替换,返回代理对象
retVal = proxy;
}
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);
}
}
}
下面分析Advisor到方法拦截器的转换过程
#AdvisedSupport
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
//跟进去
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
#DefaultAdvisorChainFactory
//config:就是proxyFactory,内部持有当前bean的所有的Advisor
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
//拦截器列表
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
//目标对象的Class
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//遍历当前bean的所有的Advisor
for (Advisor advisor : config.getAdvisors()) {
//PointcutAdvisor包含了切点信息
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
//isPreFiltered()在之前设置过,为true,说明做过类型匹配
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
//将Advisor包装成MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
//获取方法匹配器
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
//静态匹配
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
//涉及运行时匹配
if (mm.isRuntime()) {
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
//匹配成功,将拦截器加入列表
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
//不考虑
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
//说明当前Advisor匹配所有方法
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
//返回拦截器列表
return interceptorList;
}
上面这些是将Advisor转成MethodInterceptor的过程,接下来就是最核心的,拦截器调用链了。
//ReflectiveMethodInvocation核心,将代理对象,目标对象,当前方法,拦截器链都传入了
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//procced()开启拦截器调用链路
retVal = invocation.proceed();
先来看看#ReflectiveMethodInvocation,它是用来推进拦截器执行的一个类。
//ProxyMethodInvocation的顶层接口Joinpoint会提供一个proceed()方法,重点分析这个方法
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable
protected ReflectiveMethodInvocation(
Object proxy, Object target, Method method, Object[] arguments,
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
//进行一些赋值操作
this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
public Object proceed() throws Throwable {
//interceptorsAndDynamicMethodMatchers:拦截器链
//currentInterceptorIndex初始值为-1
//这个条件判断当前拦截器链执行到哪个下标,如果下标等于拦截器长度-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;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//运行时匹配失败,跳过当前拦截器,执行下一个拦截器逻辑
return proceed();
}
}
else {
//正常都会执行到这
//执行拦截器的逻辑,并且将this传入
//this:ReflectiveMethodInvocation
//这里的invoke就是MethodInterceptor的接口方法了,具体我们拿@Before和@After的实现类来看一下
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
@Before
#MethodBeforeAdviceInterceptor
//mi:ReflectiveMethodInvocation
public Object invoke(MethodInvocation mi) throws Throwable {
//首先执行@Before的方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
//再调用拦截器链中的下一个拦截器方法
return mi.proceed();
}
@After
#AspectJAfterAdvice
//mi:ReflectiveMethodInvocation
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//让拦截器链所有的拦截执行完成
return mi.proceed();
}
finally {
//再执行@After的方法
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
其他的通知类型也是类似的调用过程,具体的实现就请自行查看源码分析一下。看到这可能也有朋友还不清楚拦截器的调用链路,那么在下面我们自定义一个简单的Spring AOP,帮助大家梳理拦截器的流程。
自定义AOP
AOP核心接口及实现类
//用来驱动拦截器的执行流程
public interface MethodInvocation {
//驱动拦截器链,执行增强逻辑+被代理方法调用
Object proceed()throws Throwable;
}
//自定义拦截器接口
public interface MethodInterceptor {
//方法拦截器接口,增强逻辑,全部写在里面
Object invoke(MethodInvocation mi) throws Throwable;
}
//MethodInvocation实现类,对应ReflectiveMethodInvocation
public class MethodInvocationImpl implements MethodInvocation{
private Object target;
private Method method;
private Object[] args;
private List<MethodInterceptor> interceptorList;
//当前拦截器执行的下标
private int currentInterceptorIndex=-1;
public MethodInvocationImpl(Object target, Method method,Object[] args,List<MethodInterceptor> interceptorList){
this.target=target;
this.method=method;
this.args=args;
this.interceptorList=interceptorList;
}
@Override
public Object proceed() throws Throwable {
//如果拦截器链执行完成
if(currentInterceptorIndex==interceptorList.size()-1){
//调用目标方法
return method.invoke(target,args);
}
//到这里说明还有拦截器未执行
MethodInterceptor interceptor=interceptorList.get(++currentInterceptorIndex);
return interceptor.invoke(this);
}
}
//代理工厂
public class ProxyFactory {
//目标对象
private Object target;
//存放拦截器
private List<MethodInterceptor> interceptorList;
public ProxyFactory(Object target) {
this.target = target;
this.interceptorList = new ArrayList<>();
}
//添加Advisor,只是保证方法名一样,就不实现Advisor到MethodInterceptor的转变了
public void addAdvisor(MethodInterceptor interceptor){
this.interceptorList.add(interceptor);
}
public Object getProxy(){
return new JdkDynamicAopProxy(this).getProxy();
}
public List<MethodInterceptor> getInterceptorList() {
return interceptorList;
}
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
}
//JDK动态代理类
public class JdkDynamicAopProxy implements InvocationHandler {
private ProxyFactory proxyFactory;
public JdkDynamicAopProxy(ProxyFactory proxyFactory){
this.proxyFactory=proxyFactory;
}
//创建代理对象
public Object getProxy(){
Object target=proxyFactory.getTarget();
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
List<MethodInterceptor> interceptorList = proxyFactory.getInterceptorList();
Object target = proxyFactory.getTarget();
MethodInvocation mi=new MethodInvocationImpl(target,method,args,interceptorList);
return mi.proceed();
}
}
提供两个自定义的拦截器
//before
public class MethodBeforeInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
System.out.println("方法前置增强!");
return mi.proceed();
}
}
//after
public class MethodAfterInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try{
return mi.proceed();
}finally {
System.out.println("方法后置增强!");
}
}
}
相关测试类
public interface Animal {
public void eat();
}
public class Dog implements Animal{
@Override
public void eat() {
System.out.println("狗吃骨头!");
}
}
public class Main {
public static void main(String[] args) {
//创建目标对象
Dog dog=new Dog();
//创建代理工厂
ProxyFactory proxyFactory=new ProxyFactory(dog);
//向代理工厂添加Advisor
proxyFactory.addAdvisor(new MethodAfterInterceptor());
proxyFactory.addAdvisor(new MethodBeforeInterceptor());
//获取代理对象
Animal proxy = (Animal)proxyFactory.getProxy();
//执行目标方法
proxy.eat();
}
}
最终执行结果
方法前置增强!
狗吃骨头!
方法后置增强!
大家可以自行调试一下,这个demo相当于把AOP的核心流程都给简化并实现,相信大家看懂这个流程后,就能很好的理解Spring AOP的拦截器流程了。
以上就是Spring AOP源码分析的全部内容,涉及到的内容实在太多了,只能分析一些大概的流程,一些细节点还需自行阅读源码加以研究。