1.AOP核心接口
AnnotationAwareAspectJAutoProxyCreator
1.1查找核心接口
1.Spring通过注解**@EnableAspectJAutoProxy**开启aop切面功能:
其中有**@Import(AspectJAutoProxyRegistrar.class)**,把AspectJAutoProxyRegistrar实例加入IOC容器中;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {...}
2.AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,重写registerBeanDefinitions,在IOC容器解析配置类时(refresh-invokeBeanFactoryPostProcessors)会进行调用。
因此可以往容器中注入一个BeanDefinition;
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
...
}
3.从AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法依次进入,最终会在容器中注册一个AnnotationAwareAspectJAutoProxyCreator的bean定义,之后IOC容器会注册bean的后置处理器(refresh-registerBeanPostProcessors)。
通过AnnotationAwareAspectJAutoProxyCreator的后置处理器实现AOP的功能。
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
//注册AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
1.2核心接口继承关系
2.流程接口
解析切面:从IOC容器中获取处的所有bean的名称,从中找到所有标记了@Aspect的切面类,将所有的通知advise解析成advisor(包含advise和pointcut),并加入到缓存中;
创建代理:拿到之前解析到的所有advisors,根据其中pointcut对应去匹配matches(分为两次筛选:类级别和方法级别),匹配到的bean会根据不同情况创建动态代理createProxy;
调用代理:调用增强方法就会来到JdkDynamicAopProxy#invoke,是否暴露代理对象到线程变量ThreadLocal currentProxy中,把aop的advisor全部转化为拦截器,通过责任链模式依此调用拦截器链的invoke方法。
2.1解析切面Aspect
1postProcessBeforeInstantiation
AnnotationAwareAspectJAutoProxyCreator 实现了 InstantiationAwareBeanPostProcessor,在bean实例化前阶段(resolveBeforeInstantiation)执行父类 AbstractAutoProxyCreator的postProcessBeforeInstantiation;
//AbstractAutoProxyCreator#postProcessBeforeInstantiation
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
...
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
...
}
protected boolean isInfrastructureClass(Class<?> beanClass) {
/**
* 假如当前正在创建的Bean的class是Advice PointCut Advisor AopInfrastructureBean
* 直接跳过不需要解析
*/
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
...
return retVal;
}
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
return false;
}
2shouldSkip
跟到AspectJAwareAdvisorAutoProxyCreator#shouldSkip方法实现
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 找到候选的Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
...
return super.shouldSkip(beanClass, beanName);
}
3findCandidateAdvisors
AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors方法实现
@Override
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;
}
*4buildAspectJAdvisors
用来解析切面类,去容器中获取到所有的切面信息保存到缓存中:this.advisorsCache.put(beanName, classAdvisors);
public List<Advisor> buildAspectJAdvisors() {
...
//去容器中获取到所有的组件的名称
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍历我们从IOC容器中获取处的所有bean的名称
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
//通过beanName去容器中获取到对应class对象
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//根据class对象判断是不是切面,判断当前类有没有@Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
//是切面类加入到缓存中
aspectNames.add(beanName);
//把beanName和class对象构建成为一个AspectMetadata
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//构建切面注解的实例工厂
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//真正去获取通知对象,切面中一个通知advise就会解析成一个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 {
...
}
*5getAdvisors
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
...
//获取到切面类中除了标注了@PointCut注解的所有方法并排序(Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class,为了责任链调用)
for (Method method : getAdvisorMethods(aspectClass)) {
//遍历解析切面中的方法,将切点表达式和通知封装到InstantiationModelAwarePointcutAdvisorImpl对象中
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
...
2.2创建代理
1postProcessAfterInitialization
AnnotationAwareAspectJAutoProxyCreator 实现了 BeanPostProcessor,bean初始化后阶段(applyBeanPostProcessorsAfterInitialization)执行父类 AbstractAutoProxyCreator的postProcessAfterInitialization
//AbstractAutoProxyCreator#postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//返回动态代理实例
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
2wrapIfNecessary
//AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
...
//1.根据当前bean找到匹配的Advisor,直接去缓存中获取Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//2.创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
//3.放到缓存中
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
2.1getAdvicesAndAdvisorsForBean
//AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
@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();
}
2.1.1findEligibleAdvisors
//AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 1.从缓存中拿Advisors
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 2.判断切点是否命中当前Bean
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
// 3.对advisor进行排序,索引大的在前面
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
2.1.1.1findCandidateAdvisors
findEligibleAdvisors—>findCandidateAdvisors—>buildAspectJAdvisors,调用链同上,但这次不需要去解析而是直接去缓存中获取:this.advisorsCache.get(aspectName);
//BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
public List<Advisor> buildAspectJAdvisors() {
...
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
...
}
*2.1.1.2canApply
findEligibleAdvisors—>findAdvisorsThatCanApply—>findAdvisorsThatCanApply—>canApply,从candidateAdvisors中找到适合当前正在创建类的Advisors
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
...
//转为PointcutAdvisor类型
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//找到真正能用的增强器
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
...
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 进行类级别过滤(通过AspectJ)
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
/**
* 进行方法级别过滤
*/
//如果pc.getMethodMatcher()返回TrueMethodMatcher则匹配所有方法
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
//判断匹配器是不是IntroductionAwareMethodMatcher 只有AspectJExpressionPointCut才会实现这个接口
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
//创建一个集合用于保存targetClass 的class对象
Set<Class<?>> classes = new LinkedHashSet<>();
//判断当前class是不是代理的class对象
if (!Proxy.isProxyClass(targetClass)) {
//加入到集合中去
classes.add(ClassUtils.getUserClass(targetClass));
}
//获取到targetClass所实现的接口的class对象,然后加入到集合中
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
//循环所有的class对象
for (Class<?> clazz : classes) {
//通过class获取到所有的方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
//循环我们的方法
for (Method method : methods) {
//通过methodMatcher.matches来匹配我们的方法
if (introductionAwareMethodMatcher != null ?
// 通过切点表达式进行匹配 AspectJ方式
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
// 通过方法匹配器进行匹配 内置aop接口方式
methodMatcher.matches(method, targetClass)) {
// 只要有1个方法匹配上了就创建代理
return true;
}
}
}
return false;
}
2.2createProxy
//AbstractAutoProxyCreator#createProxy
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);
//如果设置了 <aop:aspectj-autoproxy proxy-target-class="true"/>强制使用cglib
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//真正的创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
*2.2.1createAopProxy
getProxy最终会调用到DefaultAopProxyFactory#createAopProxy
//DefaultAopProxyFactory#createAopProxy创建代理对象:
//设置了ProxyTargetClass或者没有接口,并且不是接口或者动态代理类,就会用cglib;
//设置了ProxyTargetClass或者没有接口,但是本身是接口或者动态代理类,就会用jdk;
//没有设置ProxyTargetClass或者有接口,就会用jdk。
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//判断是否设置了ProxyTargetClass或者是否有接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//是接口或者动态代理类
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//cglib代理
return new ObjenesisCglibAopProxy(config);
}
else {
//jdk动态代理
return new JdkDynamicAopProxy(config);
}
}
2.3代理类的调用
1.invoke
以JdkDynamicAopProxy为例,调用增强方法就会来到JdkDynamicAopProxy#invoke
@Override
@Nullable
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
...
Object retVal;
/**
* 这个配置是【是否暴露代理对象到线程变量ThreadLocal<Object> currentProxy中】,需要设置exposeProxy = true使用。
*如果暴露,在jdk代理中,在本类方法A中调用本类方法B,不会再次执行动态代理方法。
*/
if (this.advised.exposeProxy) {
//把代理对象暴露到线程变量中
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取目标对象
target = targetSource.getTarget();
//获取目标对象的class
Class<?> targetClass = (target != null ? target.getClass() : null);
//把aop的advisor全部转化为拦截器,通过责任链模式依此调用拦截器的invoke方法
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();
}
...
2.proceed
ReflectiveMethodInvocation#proceed,递归调用proceed,直到执行到最后一个拦截器执行invokeJoinpoint,就是调用被增强的方法
@Override
@Nullable
public Object proceed() throws Throwable {
//从-1开始,结束条件执行目标方法是下标=拦截器的长度-1(执行到了最后一个拦截器)
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
/**
* 获取第一个方法拦截器使用的是前++
*/
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
//调用第一个拦截器的invoke方法,传入的是this,当前的方法拦截器对象
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
2.0ExposeInvocationInterceptor#invoke
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
//记录当前正在执行的拦截器
invocation.set(mi);
try {
//递归调用
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
2.1AspectJAfterThrowingAdvice#invoke
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//执行下一个拦截器
return mi.proceed();
}
catch (Throwable ex) {
//抛出异常
if (shouldInvokeOnThrowing(ex)) {
//执行异常通知
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
2.2AfterReturningAdviceInterceptor#invoke
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//本拦截器返回通知拦截器,所抛出异常就不会执行返回通知的方法,执行下一个拦截器(后置拦截器对象)
Object retVal = mi.proceed();
//返回通知方法
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
2.3AspectJAfterAdvice#invoke
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//本拦截器是后置通知拦截器对象,执行下一个通知
return mi.proceed();
}
finally {
//后置通知的方法总是会被执行 因为是finally包裹的
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
2.4MethodBeforeAdviceInterceptor#invoke
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//本拦截器是前置通知拦截器对象,先执行前置通知的方法
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
//执行下一个拦截器,但是该拦截器是最后一个了,那么就会调用目标方法
return mi.proceed();
}
3.jdk和cglib区别
jdk动态代理代理的是***接口***,jdk底层会自己根据接口新生成***一个***动态代理的$Proxy.class字节码文件,该.class文件会***实现***需要代理的接口并重写具体方法,这也是为什么jdk动态代理一定要有接口;通过***反射***的方式调用具体方法;在jdk代理中,在本类方法A中调用本类方法B,***不会再次***执行动态代理方法。
执行Proxy.newProxyInstance—>JDK生成$Proxy.class字节码文件—>执行方法A—>会去调用InvocationHandler.invoke方法—>通过反射调用具体方法。
cglib代理的是***具体实现类***,底层利用ASM组件根据具体类生成***多个***cglib.class字节码文件,该.class文件会***继承***需要代理的具体类并重写具体方法,所以cglib代理不需要指定接口;***直接调用***实现了被代理类的动态代理类(子类)方法;在cglib代理中,在本类方法A中调用本类方法B,***会重复***执行动态代理方法。
执行enhancer.create—>ASM生成多个cglib.class字节码文件—>执行方法A—>会去调用MethodInterceptor.intercept方法—>直接调用子类具体方法。