基于@Aspect注解实现的SpringBoot AOP源码
用法
导包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
使用
@Slf4j
@Component("myAop")
@Aspect
public class SunpyAopBean {
@Pointcut("execution(public void com.sunpy.simpleweb.bean.SunpyBean.doPrint())")
public void cutMethod() {
}
@Before("cutMethod()")
public void beforeExecute() {
log.info("================================= beforeExecute");
}
}
结果
2023-05-07 18:22:13.768 INFO [http-nio-3800-exec-1] c.s.simpleweb.bean.SunpyAopBean.beforeExecute - ================================= beforeExecute
2023-05-07 18:22:13.779 INFO [http-nio-3800-exec-1] c.sunpy.simpleweb.bean.SunpyBean.doPrint - ================================= doPrint
流程图
AOP的源码步骤
1. 通过自动装配,注入一个AnnotationAwareAspectJAutoProxyCreator(这是一个实现了BeanPostProcessor的bean后置处理器),那么生成代理对象的方法在initializeBean方法中实现。
2. 被代理的原生bean,如果需要aop代理,那么会调用createProxy方法生成代理bean。
3. 原本应该返回原生bean,那么此时代理bean会替换到原生bean。
4. 当调用的实现,执行拦截的方法,先获取增强器Advice,然后执行增强的方法,最后再执行被拦截的方法。
网图:
SpringBoot AOP自动装载
在invokeBeanFactoryPostProcessors方法中完成
- 入口:parse方法委派给process方法。
- process方法委派给processGroupImports方法。
- grouping.getImports()方法读取META-INF/spring.factories文件下的EnableAutoConfiguration中的AopAutoConfiguration。
- 调用processImports方法,该方法为执行@Import注解的方法。
- AopAutoConfiguration第三方spring-boot-starter-aop集成注入的bean。
代码
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
static class JdkDynamicAutoProxyConfiguration {
}
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
static class CglibAutoProxyConfiguration {
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
static class ClassProxyingConfiguration {
@Bean
static BeanFactoryPostProcessor forceAutoProxyCreatorToUseClassProxying() {
return (beanFactory) -> {
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
};
}
}
}
说明:@Import注解使用processImports方法注入AspectJAutoProxyRegistrar这个bean。
注入AnnotationAwareAspectJAutoProxyCreator到spring容器
AspectJAutoProxyRegistrar类通过EnableAspectJAutoProxy注入(@Import)进Spring容器。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
// 自动创建AspectJ代理对象这个bean
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册一个AnnotationAwareAspectJAutoProxyCreator到Spring容器中
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
// 判断使用cglib代理
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// 判断暴露当前的代理对象
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
registerAspectJAnnotationAutoProxyCreatorIfNecessary方法
注册一个AnnotationAwareAspectJAutoProxyCreator到spring容器(spring容器 => beanFactory => beanDefinitionMap)。
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 判断是否已经存在AnnotationAwareAspectJAutoProxyCreator这个bean
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 {
// 不存在该BeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
// 放到beanDefinitionMap中
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}
委派给registerBeanDefinition将AnnotationAwareAspectJAutoProxyCreator放到beanDefinitionMap中
- 本质上AnnotationAwareAspectJAutoProxyCreator还是BeanPostProcessor
Spring IOC过程中initializeBean方法,对后置处理器bean对符合要求的bean进行动态代理
- 对bean的动态代理,在springboot的bean后置处理器中执行,也就是spring ioc的过程中来实现的。
- SpringBoot中的bean后置处理器位置:initializeBean方法(最终来源于getBean方法)中的applyBeanPostProcessorsAfterInitialization方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 遍历在BeanFactory中的BeanPostProcessor的集合
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
// 执行后处理器
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
AbstractAutoProxyCreator类之postProcessAfterInitialization方法:
找到适合代理的bean,然后使用配置的拦截器创建一个代理。
// 对bean执行初始化后处理
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
// 使用类全名和name构造一个key,格式:beanClass.getName() + "_" + beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 如果它适合被代理,那么需要封装指定bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
wrapIfNecessary方法
前面就是校验bean是否已经被处理过,或者干脆不需要增强。而真正开始创建代理是在getAdvicesAndAdvisorsForBean方法,至于给哪个bean生成代理等操作也都是从该方法开始的。
// 如果bean符合被代理的需要,那么将bean包装起来
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && 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;
}
// 如果存在增强方法则创建代理
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;
}
说明:这里面有两个方法,getAdvicesAndAdvisorsForBean方法和createProxy方法。
getAdvicesAndAdvisorsForBean方法,主要作用查找匹配bean的Advisors集合。
createProxy方法,主要作用对Advisor集合非空的bean创建代理类。
核心方法1,getAdvicesAndAdvisorsForBean方法,查找匹配bean的Advisors集合
1. getAdvicesAndAdvisorsForBean方法
// 查找匹配bean的Advisor集合
@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();
}
2. 委派给AbstractAdvisorAutoProxyCreator类之findEligibleAdvisors方法:
// 寻找与beanClass合适的Advisor
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 调用父类方法加载配置文件中的AOP声明
// 提取增强器Advisor(普通增强器、同步实例化增强器等)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 寻找匹配的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 添加默认DefaultPointcutAdvisor
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
3. AnnotationAwareAspectJAutoProxyCreator类之findCandidateAdvisors方法,提取增强器Advisor
- 获取所有bean名称
- 挑选出被@Aspect注释的bean名称
- 基于bean名称构建元数据工厂(MetadataAwareAspectInstanceFactory),该工厂可以创建@Aspect注释的bean
- 最后使用全局变量advisorFactory,将MetadataAwareAspectInstanceFactory构建成一组Advisor对象
@Override
protected List<Advisor> findCandidateAdvisors() {
// 原始构建Advisor的方式,找到超类的Advisors增强器
List<Advisor> advisors = super.findCandidateAdvisors();
// 重点地方,提取增强器Advisor,然后添加到Advisor的List中
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
基于@Aspect注解构建Advisor对象,然后放到了advisors容器中
- AopUtils类之findAdvisorsThatCanApply方法,寻找匹配的增强器
// 寻找匹配的增强器
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 过滤已经得到的advisors
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
// 寻找所有增强器中适用于当前class的增强器
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
// 处理引介增强
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;
}
// 对于普通bean处理
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
核心方法2,AbstractAutoProxyCreator类之createProxy方法,使用指定的Bean创建aop代理
- 获取当前类中的属性。
- 添加代理接口。
- 封装Advisor并加入到ProxyFactory中。
- 设置要代理的类。
- Spring提供定制函数customizeProxyFactory,子类可以在该函数中进一步封装。
- 进行获取代理操作。
// 使用指定的Bean创建aop代理
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
ProxyFactory proxyFactory = new ProxyFactory();
// 获取当前类中的相关属性
proxyFactory.copyFrom(this);
// 检查proxyTargetClass属性的设置,如果为false,那么采用jdk基于接口的jdk代理,
// 如果为true,那么采用cglib代理
if (!shouldProxyTargetClass(beanClass, beanName)) {
// Must allow for introductions; can't just set interfaces to
// the target's interfaces only.
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
for (Class<?> targetInterface : targetInterfaces) {
// 添加代理接口
proxyFactory.addInterface(targetInterface);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
// 将Advisor封装加入到ProxyFactory中
proxyFactory.addAdvisor(advisor);
}
// 设置要代理的类
proxyFactory.setTargetSource(targetSource);
// 定制代理,子类可以进一步封装
customizeProxyFactory(proxyFactory);
// 用来控制代理工厂被配置之后,是否还允许修改通知
// 缺省值为false(即在代理被配置之后,不允许修改代理的配置)
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 获取代理
return proxyFactory.getProxy(this.proxyClassLoader);
}
DefaultAopProxyFactory类之createAopProxy方法,创建AopProxy代理对象
- 如果proxyTargetClass设置为false或者存在代理接口,那么直接创建Jdk代理对象,返回。
- 否则如果目标类是接口,那么就创建Jdk代理对象,返回。
- 如果上面都不满足,那么直接创建cglib代理对象,返回。
// 创建代理简单工厂,依据配置创建代理对象
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
// 根据AdvisedSupport(Aop配置管理器),来获取对应的代理对象
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// proxyTargetClass:目标类本身被代理而不是目标类的接口
// hasNoUserSuppliedProxyInterfaces:是否存在代理的接口
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
// 如果目标类为null,抛出异常
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
// 如果目标类是接口,就创建Jdk代理对象
if (targetClass.isInterface()) {
return new JdkDynamicAopProxy(config);
}
// 默认创建cglib代理对象,进入这句话
return new ObjenesisCglibAopProxy(config);
}
else {
// 创建Jdk代理对象
return new JdkDynamicAopProxy(config);
}
}
创建CglibAopProxy对象
public ObjenesisCglibAopProxy(AdvisedSupport config) {
super(config);
}
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}
CglibAopProxy.getProxy方法,获取cglib创建的代理对象
代码
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
CglibAopProxy 的内部类CglibAopProxy.DynamicAdvisedInterceptor#intercept方法
代码调用阶段
DynamicAdvisedInterceptor.intercept方法,cglib拦截方法
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
// 判断是否暴露代理类
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// 获取需要被代理的目标类
target = targetSource.getTarget();
// 获取被代理类的Class文件
Class<?> targetClass = (target != null ? target.getClass() : null);
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 不存在增强器Advice,那么直接执行原目标类的方法
if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
try {
retVal = methodProxy.invoke(target, argsToUse);
}
catch (CodeGenerationException ex) {
CglibMethodInvocation.logFastClassGenerationFailure(method);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
}
else {
// 创建方法代理,执行invoke方法
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
委派给ReflectiveMethodInvocation.proceed()方法执行,执行内容还是invoke方法调用。
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 记录下当前拦截器的数量,获取拦截增强Advice
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;
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 {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// 执行拦截方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
参考
https://blog.csdn.net/u011523825/article/details/126990788
https://zhuanlan.zhihu.com/p/55413774?utm_id=0
https://blog.csdn.net/z_Jimmy/article/details/125614690