您的位置:首页 > 编程语言 > ASP

Springboot源码分析之EnableAspectJAutoProxy

2019-08-22 22:26 1571 查看

摘要:

Spring Framwork
的两大核心技术就是
IOC
AOP
AOP
Spring
的产品线中有着大量的应用。如果说反射是你通向高级的基础,那么代理就是你站稳高级的底气。
AOP
的本质也就是大家所熟悉的
CGLIB
动态代理技术,在日常工作中想必或多或少都用过但是它背后的秘密值得我们去深思。本文主要从
Spring AOP
运行过程上,结合一定的源码整体上介绍
Spring AOP
的一个运行过程。知其然,知其所以然,才能更好的驾驭这门核心技术。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
//表明该类采用CGLIB代理还是使用JDK的动态代理
boolean proxyTargetClass() default false;
/**
* @since 4.3.1 代理的暴露方式:解决内部调用不能使用代理的场景  默认为false表示不处理
* true:这个代理就可以通过AopContext.currentProxy()获得这个代理对象的一个副本(ThreadLocal里面),从而我们可以很方便得在Spring框架上下文中拿到当前代理对象(处理事务时很方便)
* 必须为true才能调用AopContext得方法,否则报错:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
*/
boolean exposeProxy() default false;
}

所有的

EnableXXX
驱动技术都得看他的
@Import
,所以上面最重要的是这一句
@Import(AspectJAutoProxyRegistrar.class)
,下面看看它

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册了一个基于注解的自动代理创建器   AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
//表示强制指定了要使用CGLIB
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//强制暴露Bean的代理对象到AopContext
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}

AspectJAutoProxyRegistrar
是一个项容器注册自动代理创建器

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

说明

spring
容器的注解代理创建器就是
AnnotationAwareAspectJAutoProxyCreator

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//这里如果我们自己定义了这样一个自动代理创建器就是用我们自定义的
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
/**
*用户注册的创建器,必须是InfrastructureAdvisorAutoProxyCreator
*AspectJAwareAdvisorAutoProxyCreator,AnnotationAwareAspectJAutoProxyCreator之一
*/
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//若用户自己没有定义,那就用默认的AnnotationAwareAspectJAutoProxyCreator
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
//此处注意,增加了一个属性:最高优先级执行,后面会和@Async注解一起使用的时候起关键作用
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}

我们就成功的注入了一个Bean

AnnotationAwareAspectJAutoProxyCreator
基于注解的自动代理创建器

Spring中自动创建代理器

由此可见,

Spring
使用
BeanPostProcessor
让自动生成代理。基于
BeanPostProcessor
的自动代理创建器的实现类,将根据一些规则在容器实例化
Bean
时为匹配的
Bean
生成代理实例。

AbstractAutoProxyCreator
是对自动代理创建器的一个抽象实现。最重要的是,它实现了
SmartInstantiationAwareBeanPostProcessor
接口,因此会介入到
Spring IoC
容器
Bean
实例化的过程。

SmartInstantiationAwareBeanPostProcessor
继承
InstantiationAwareBeanPostProcessor
所以它最主要的 职责是在
bean
的初始化前,先会执行所有的
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
,谁第一个返回了不为
null
Bean
,后面就都不会执行了 。然后会再执行
BeanPostProcessor#postProcessAfterInitialization

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}

说明:这个方法是

spring
的三级缓存中的其中一环,当你调用
Object earlySingletonReference = getSingleton(beanName, false);
时候就会触发,其实还有一个地方
exposedObject = initializeBean(beanName, exposedObject, mbd);
也会触发导致返回一个代理对象。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

强调: 这2个地方虽然都有后置增强的作用,但是

@Async
所使用的
AsyncAnnotationBeanPostProcessor
不是
SmartInstantiationAwareBeanPostProcessor
的实现类,所以此处会导致
@Transactional
@Async
处理循环依赖时候的不一致性。对于循环依赖后续会有单独章节进行分享。

AbstractAdvisorAutoProxyCreator

如何创建代理对象后续文章在进行分析。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: