平时用aop用的很爽,今天决定研究一下源码,基于spring+aspectj来讲
- 本文探究的源码哦,如果读者想吃透此篇文章,以下知识必不可少
- spring aop调用流程手把手带你debug
- 深入jdk动态代理源码解析
- 深入cglib动态代理源码解析 TODO
AOP
- 定义:一种切面的编程思想
具体实现有:
- springAOP
- spring+aspectj
底层实现:cglib、jdk动态代理
@EnableAspectJAutoProxy(proxyTargetClass = false)
通过这个注解我们可以干涉aop的代理逻辑,此注解给ioc容器添加了一个组件名字为AspectJAutoProxyRegistrar
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
AspectJAutoProxyRegistrar
给aop的实现注入额外的组件,以及添加EnableAspectJAutoProxy注解上的内容
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AspectJAutoProxyRegistrar() {
}
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//给ioc容器中注入组件
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//添加EnableAspectJAutoProxy注解上的内容
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
registerAspectJAnnotationAutoProxyCreatorIfNecessary
作用:给ioc容器中注册了一个组件
- beanName:internalAutoProxyCreator
- beanClass:AnnotationAwareAspectJAutoProxyCreator
注意点:看这俩个类的继承关系,AbstractAutoProxyCreator是AnnotationAwareAspectJAutoProxyCreator的父类,aop的很多操作都在AbstractAutoProxyCreator中进行的,且顶层父类是InstantiationAwareBeanPostProcessor而且是一个BeanPostProcessor,这个在下文很重要哦。
@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")) {
//生成一个internalAutoProxyCreator的BeanDefinition
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) {
//设置beanName = internalAutoProxyCreator的beanClass = AnnotationAwareAspectJAutoProxyCreator
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//ioc容器连internalAutoProxyCreator都还没有,先注册internalAutoProxyCreator的beanDefinition
else {
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}
registerBeanPostProcessors
为spring添加内部的后置处理器:
- 获取PriorityOrdered类型的后置处理器,添加到专属map然后排序
- 获取Ordered类型的后置处理器,添加到专属map然后排序(注册AnnotationAwareAspectJAutoProxyCreator过程在此发生)
- 获取非PriorityOrdered、Ordered类型的后置处理器,添加到专属map然后排序
- 把所有的这些map添加到总map中一并添加作为spring内置后处理器
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
/**
* Ordered类型的后置处理器的名字添加到orderedPostProcessorNames中
*/
orderedPostProcessorNames.add(ppName);
}
else {
/**
* 非Ordered类型的后置处理器的名字添加到orderedPostProcessorNames中
*/
nonOrderedPostProcessorNames.add(ppName);
}
}
/**
* 对优先注册的后置处理器进行排序
*/
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
/**
* 先注册PriorityOrdered类型的后置处理器
*/
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
/**
* 对order类型的后置处理器进行排序
*/
sortPostProcessors(orderedPostProcessors, beanFactory);
/**
* 第二注册ordered类型的后置处理器
*/
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
/**
* 最后注册其他类型的后置处理器
*/
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
/**
* 对所有注册的后置处理器进行排序
*/
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
AnnotationAwareAspectJAutoProxyCreator本质也是Ordered类型
看源码不可能一行行代码都看,看aop的源码亦是如此,不搞虚的直接上干货,直接进入refresh()方法进行debug
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//本文不做分析
this();
//本文不做分析
this.register(componentClasses);
//重点在这
this.refresh();
}
refresh
里面的代码几万行,由于我已经看过了源码,直接进入告诉读者aop的实现与此方法有关,点它
- this.finishBeanFactoryInitialization(beanFactory); 进行bean初始化
public void refresh() throws BeansException, IllegalStateException {
synchronized(this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
//进行bean初始化
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var10) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
}
this.destroyBeans();
this.cancelRefresh(var10);
throw var10;
} finally {
this.resetCommonCaches();
contextRefresh.end();
}
}
}
finishBeanFactoryInitialization
- beanFactory.preInstantiateSingletons(); 进行bean的实例化
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
//对一些特殊的bean优先获取,并且优先初始化
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
//getBean是重点,下文着重分析
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons
实例化bean,不同类型的bean有不同的逻辑判断进行处理,然后进行相应的getBean操作
- 工厂bean情况
- 单例bean情况
- 抽象bean
- 是否是懒加载的bean
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
//只有是抽象bean的情况下才会有如下的逻辑判断
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
if (this.isFactoryBean(beanName)) {
//工厂bean的获取前面加&符号
bean = this.getBean("&" + beanName);
break;
}
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
我们仔细观察preInstantiateSingletons中的代码,看起来很多但是只有是抽象的bean才会走这些个代码逻辑
其他类型的bean就直接走this.getBean(beanName)了
研究个捶捶抽象bean的实例化,直接debug进入this.getBean(beanName)一探究竟
doGetBean
注意此dogetBean的入参,下文还有另外的dogetBean,俩个是不同的哟
- doGetBean(String name,Class requiredType, Object[] args, boolean typeCheckOnly)
spring简直是个套娃🪆,getBean本质调用的是doGetBean方法
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
//规范化beanName,有些bean具有别名,规范化一下
String beanName = this.transformedBeanName(name);
//从一、二、三级缓存中获取单例对象重点
Object sharedInstance = this.getSingleton(beanName);
Object beanInstance;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取bean实例对象
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
}
//如果从一、二、三级缓存中获取到了bean实例对象,那么下面一大串的else代码都不会执行了,直接执行 return this.adaptBeanInstance(name, beanInstance, requiredType);
else {
//当前正在创建的bean不能被获取,会抛出异常
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//父beanFactory中存在此bean,或者虽然父beanFactory不存在但是包含此BeanDefinition,从父beanFactory中获取bean
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
//获取此beanName的所有相关信息合并成一个RootBeanDefinition
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var12;
if (dependsOn != null) {
var12 = dependsOn;
int var13 = dependsOn.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dep = var12[var14];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
//先创建依赖的bean
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var31) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var31);
}
}
}
//一、二、三级缓存都获取不到单实例对象,且当前要获取的bean没有依赖别的bean,直接再次尝试单实例对象。获取不到那么进行创建单实例对象的操作
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
//从单实例对象中获取bean实例对象
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//多实例bean的创建流程 先不管TODO
else if (mbd.isPrototype()) {
var12 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
beanInstance = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ��" + beanName + "'");
}
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
beanInstance = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var30) {
throw new ScopeNotActiveException(beanName, scopeName, var30);
}
}
} catch (BeansException var32) {
beanCreation.tag("exception", var32.getClass().toString());
beanCreation.tag("message", String.valueOf(var32.getMessage()));
this.cleanupAfterBeanCreationFailure(beanName);
throw var32;
} finally {
beanCreation.end();
}
}
return this.adaptBeanInstance(name, beanInstance, requiredType);
}
抽丝剥茧分析dogetBean
一、二、三级缓存介绍
- 一级缓存:singletonObjects 单例池 缓存的是单例对象
- 二级缓存:earlySingletonObjects
- 三级缓存:singletonFactories 缓存的是一个lamada表达式(只有存在循环依赖的情况下,三级缓存才派的上用场)
三级缓存:a(b)、b(a) 俩个bean有此依赖关系,getBean(a)大概流程如下
- 从三层缓存中获取a,获取失败
- 把a放入三级缓存
- 开始创建a,a进行属性的时候要填充b,此时b还未创建开始创建b
- 创建b,在b属性填充的时候发现要填充a,发现a自个都没创建完成呢
- b只好尝试属性填充a = getBean(beanName = “a”)
- getBean(beanName = “a”):再次从三层缓存中获取a,此时三级缓存中可以拿到带有a原始对象的lamada表达式,然后lamada表达式就创建了一个a的代理对象
- b:美滋滋的完成了创建流程,nice呀
- a:哦哄哄,b创建完成了呀,接着步骤3的操作,完成了a的属性填充了
- a:美滋滋的完成了创建流程,nice呀
- 循环依赖 :我哭了呀,a、b这俩狗子打死☠️
dogetBean中的getSingleton() 是从一、二、三级缓存中依次获取单例对象。
- 为什么从三级缓存获取到代理对象后,要把此对象放入二级缓存?
- 为什么从三级缓存获取到代理对象后,要移除三级缓存中的内容?
看如下的代码不知读者是否有这些疑惑呢?下文会来进行分析
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
/**
* 先从单例池中获取bean(一级缓存)
*/
Object singletonObject = this.singletonObjects.get(beanName);
/**
* 如果单例池获取不到,且此bean正在创建
*/
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
/**
* 从earlySingletonObjects获取bean(二级缓存)
*/
singletonObject = this.earlySingletonObjects.get(beanName);
/**
* 从earlySingletonObjects中获取不到bean,且允许循环依赖
*/
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
/**
* 再次尝试从单例池中获取bean(一级缓存)
*/
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
/**
* 从earlySingletonObjects获取bean(二级缓存)
*/
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
/**
* 从三级缓存中获取singletonFactory的lamada表达式,
* 从lamada表达式中获取代理对象放入二级缓存
* 将beanname从三级缓存中移除
*/
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
多实例的bean在三层缓存中拿取不到的话,来到这会直接报错
标记bean是正在创建
doGetBean中的这段代码和@DependOn有关,spring会优先给指定的bean进行创建(@DependOn(bean)指明了的bean)
再次尝试获取bean,获取不到bean后执行lamada表达式中的createBean()。
getSingleton(String beanName, ObjectFactory<?> singletonFactory) 注意此getSingleton的入参不一样
- 尝试从一级缓存中获取bean
- 获取不到bean然后执行lamada表达式中的createBean()
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
/**
* 从singletonObjects单例池中再次尝试获取bean
*/
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
/**
* 还是获取不到bean,在创建bean前做一些操作
*/
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
/**
* 开始创建bean,执行lamada表达式中的createBean()
*/
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException ex) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
/**
* 创建好bean之后做一些操作
*/
afterSingletonCreation(beanName);
}
/**
* 创建好bean之后newSingleton==true,把bean添加进单例池
*/
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
createBean
createBean主要做了俩件事情
- resolveBeforeInstantiation():在真正的创建bean之前,给予我们返回代理对象的机会
- doCreateBean():获取代理对象失败进行 this.doCreateBean(beanName, mbdToUse, args);
代码很多,下文拆分小块来研究
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
/**
* 实例化bean之前看是否有机会获取代理对象
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
/**
* 获取代理对象成功、直接返回代理对象
*/
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
/**
* 开始创建bean
*/
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
/**
* bean创建好了,直接返回
*/
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
resolveBeforeInstantiation
- resolveBeforeInstantiation():在真正的创建bean之前,给予我们返回代理对象的机会
代码很多拆分小块下面图文讲解
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
/**
* 实例化前置处理器,如果这里没有创建好代理对象那么不会执行实例化后置处理器!!!
* 如果此处能aop,直接返回aop过后的对象就好了
*/
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
/**
* 初始化的后置处理器,没有提前aop,此处进行aop
*/
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
/**
* 返回的bean为null,说明获取代理对象不成功,执行创建bean的逻辑
*/
return bean;
}
实例化前置处理器(postProcessBeforeInstantiation)
- 如果advisedBeans对需要增强的bean已经标记过,直接return null;也不会执行PostProcessorsAfterInitialization()了。
- 只有是自定义的目标对象,此处才会进行创建代理
- 如果当前解析的bean是基类,也把当前解析的bean放入advisedBeans中
初始化后置处理器:postProcessAfterInitialization
- wrapIfNecessary:aop操作
- 正常的bean再此处进行aop(正常的bean:没有涉及到循环引用的bean,自然用不到三级缓存,earlyProxyReferences中自然也没有值,乖乖的进行aop)
resolveBeforeInstantiation小结:只有存在自定义的目标对象(详情可以研究一下如下这行代码),此处才有可能返回一个代理对象。
doCreateBean
这个doCreateBean是核心,读者可能看的有点看懵逼了,再来贴一遍doCreateBean的代码吧
现在的doGetBean
- protected Object doCreateBean(String beanName, RootBeanDefinition
mbd, Object[] args)
上文的doGetBean
- doGetBean(String name,Class requiredType, Object[] args, boolean typeCheckOnly)
俩个doGetBean是不同的哟额,代码有点长下文抽丝剥茧此doGetBean分析。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
/**
* 此时的bean是个空壳子
*/
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
/**
* 这里又有一个后置处理器,以后在研究哎
*/
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
/**
* 如果当前bean正在创建、允许循环依赖、是单实例的,放入三级缓存
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
/**
* 初始化bean操作
*/
Object exposedObject = bean;
try {
/**
* 进行属性填充赋值
*/
populateBean(beanName, mbd, instanceWrapper);
/**
* 开始初始化bean
*/
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
/**
* 先不管这里 TODO
*/
if (earlySingletonExposure) {
/**
* a添加
*/
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
/**
*bean创建且初始化成功、doCreateBean成功,返回bean
*/
return exposedObject;
}
先获取一个bean的封装对象,缓存中获取不到的话,进行创建一个bean包装对象
spring为我们提供的扩展点之一:
- MergedBeanDefinitionPostProcessor:在bean进行属性填充、初始化之前允许我们开发人员进行对bean定义的修改,读者可以细看此后置处理器。此时bean中所依赖的bean为null
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName,
mbd, bean));
- 把当前bean包装成一个lamada表达式存入三级缓存的条件:如果当前bean正在创建、允许循环依赖、是单实例的(三级缓存一旦触发,那么会为三级缓存中的原始对象创建代理对象)
- 三级缓存触发时机:存在循环依赖。在创建依赖bean的时候从三层缓存中获取bean,但是一、二级缓存获取不到,此时执行三级缓存中的lamada表达式
populateBean: 对当前创建的bean包装对象的进行属性填充赋值(重要)
- 里面涉及到@Autowire、@Resource、循环依赖的源码问题本文暂不分析(重要)彻底搞懂spring循环依赖
- 如果在填充依赖的bean时候,依赖的bean获取不到,那么里面还有一次getBean(beanName = “依赖bean的name”)操作
exposedObject = initializeBean(): 进行初始化bean(重要),最后返回创建好的exposedObject对象
此处返回的bean对象到底是返回给谁呢?我还是在贴一遍代码吧
- exposedObject被赋值给shareInstance
- 对shareInstance做些操作然后返回给上级
最终getBean(beanName)拿到的就是adaptBeanInstance(name,beanInstance,requireType)返回的bean了。到此一个大概的获取bean的流程大概是走了一遍了。
populateBean细节解读
populateBean:对bean进行属性填充赋值
- 里面涉及到@Autowire、@Resource注入方式的源码
- 循环依赖源码解析
- 属性注入过程的流程
代码有点多,下面图文讲解
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
/**
* bean包装为null
*/
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
} else {
/**
* 属性填充为null
*/
// Skip property population phase for null instance.
return;
}
}
/**
* 实例化之后的后置处理器,spring扩展点
* 在进行属性填充之前调用InstantiationAwareBeanPostProcessor这个后置处理器中的postProcessAfterInstantiation
*/
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/**
* postProcessAfterInstantiation默认为true
* spring扩展点,可以修改postProcessAfterInstantiation的值,让属性填充不进行
*/
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
/**
* 获取当前要填充bean的所有属性
*/
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
/**
* 与bean的注入方式有关
*/
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
/**
* 如果要填充的属性注入方式是为AUTOWIRE_BY_NAME,自动注入为by_name
*/
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
/**
* 里面涉及到循环依赖问题,依赖bean的创建
*/
autowireByName(beanName, mbd, bw, newPvs);
}
/**
* 如果要填充的属性注入方式是为AUTOWIRE_BY_TYPE,自动注入为by_type
*/
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
/**
* InstantiationAwareBeanPostProcessor,spring为我们提供的扩展点
*/
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
/**
* 此处完成属性的自动注入,@Autowire注解@Resource注解的原理在里面
*/
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
- spring扩展点之InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation:属性填充之前执行,可以对指定bean不进行属性填充
解析注入模型
- 通过类型注入:byType
- 通过name注入:byName
此时并没有完成真正意义上的属性注入!只是将所需注入的bean属性(getBean(propertyName))获取放入到pvs中
- getBean():如果get不到bean,且get的bean是正常的,那么走正常创建bean流程
- getBean():如果要get的bean存在循环依赖关系,那么从三级缓存中获取创建bean的代理对象
- getBean():每次getBean()都会先从三层缓存中尝试去获取bean,在走之后的流程
真正的属性注入在这里,这里面涉及到@Autowire、@Resource底层注入原理
initializeBean细节解读
接下来扣细节之initializeBean(),initializeBean才是正常bean进行aop的地方。下面配图文讲解
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
/**
* 调用实现了Aware接口的加强方法。spring的扩展点
*/
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
/**
* 初始化前置处理器
*/
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
/**
* 此时的bean赋值、创建完成。接着调用初始化方法,
* 里面有spring的扩展点
*/
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()) {
/**
* 如果是没有涉及到循环依赖的bean,在此处正常创建代理。
* 初始化的后置处理器,里面如果有必要进行aop操作
*/
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
我已经提前阅读过了源码,initializeBean中的这些代码与aop无关,本文只研究aop的原理,这些代码的研究暂且直接跳过
(没有涉及到循环依赖的bean)正常bean在此处进行aop(创建代理对象)
注意点:看这俩个类的继承关系,AbstractAutoProxyCreator是AnnotationAwareAspectJAutoProxyCreator的父类,aop的很多操作都在AbstractAutoProxyCreator中进行的,且顶层父类是InstantiationAwareBeanPostProcessor而且是一个BeanPostProcessor
本质是遍历调用所有的BeanPostProcessor.postProcessAfterInitialization()
- 由于之前@EnableAspectJAutoProxy给容器注册过组件AnnotationAwareAspectJAutoProxyCreator,且AbstractAutoProxyCreator是AnnotationAwareAspectJAutoProxyCreator的父类,故也会执行AbstractAutoProxyCreator中的postProcessAfterInitialization()
- 提前aop概念:执行三级缓存中的lamada表达式,进行的aop操作
- 会调用当时@EnableAspectJAutoProxy给容器注册的组件(AbstractAutoProxyCreator)中的postProcessAfterInitialization。(如果没有提前进行aop,那么进行aop操作)
wrapIfNecessary
- 再次过滤哪些bean是需要被排除创建代理对象的
- 获取被代理对象的advices、advisers
- aop创建代理对象
代码有点多,下文拆分小块图文讲解
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
/**
* 增强对象的map中有此bean,如果为false表明此bean已经增强过了不需要执行下面的aop逻辑了,直接返回此bean
*/
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
/**
* 此bean是否是切点或者是原始对象,满足条件放入增强bean的map,同时设置advisedBeans[cacheKey,false],表示此bean不需要被代理了
*/
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
/**
* 获取此bean的所有通知、Advisor。指定的拦截器
*/
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
/**
* 增强bean中放入此bean的信息,表明此bean需要被增强
*/
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;
}
获取当前bean advice、Advisors这些东西,存在即进行aop创建代理对象
createProxy:开始创建代理对象咯。代码很多关注重点即可
- createProxy中new了一个ProxyFactory
- ProxyFactory里面存放了目标对象、所有的增强通知
最终通过ProxyFactory把所有的增强逻辑织入代理对象然后返回
最终我们终于来到了这,熟悉的味道呀。
- jdk动态代理:基于接口实现。jdk创建代理的逻辑参照,没啥差别 jdk源码解读 带你手把手写一个自己的jdk
- cglib动态代理:基于继承实现。源码暂且未研究过
到此initializeBean()之aop源码创建流程解读算是完成了。到这可能有些读者已经蒙圈了。我再来大致梳理一下aop创建的完整流程。
正常bean aop的创建流程梳理
现有a(b)、b(a) 俩个bean有此依赖关系,getBean(a)大概流程如下
- 从三层缓存中获取a,获取失败
- 开始创建a,a进行属性填充,不存在循环依赖哦耶,属性填充顺利
- exposedObject = initializeBean(beanName, exposedObject, mbd); 里面进行aop操作(生成代理对象)
- 由于没有提前aop,那么也不会再次从三层缓存中获取bean对象
- 创建a成功,哦耶getBean成功了
涉及到循环依赖的bean aop创建流程梳理
现有a(b)、b(a) 俩个bean有此依赖关系,getBean(a)大概流程如下
- 从三层缓存中获取a,获取失败
- 创建a之前,把a放入三级缓存
- 开始创建a,a进行属性的时候要填充b,此时b还未创建开始创建b
- 开始创建b,在b属性填充的时候发现要填充a,发现a自个都没创建完成呢
- b只好尝试属性填充a = getBean(beanName = “a”)
- getBean(beanName = “a”):再次从三层缓存中获取a,此时三级缓存中可以拿到带有a原始对象的lamada表达式,依据lamada表达式就创建了a的代理对象,同时把代理对象放入二级缓存,最终代理对象返回给getBean(beanName = “a”)
- b:美滋滋,我终于是个完整的人了哦耶,nice呀
- a:哦哄哄,b是个健康的人了终于可以来我公司做事了,接着步骤3的操作,完成了a的属性填充b。
- a:美滋滋,我终于也是个完整的人了哦耶
- 但是!a虽然此时是完成了创建,可此时的a还不是代理对象呀
- 进行属性赋值、初始化之后,还有最后一步:如果是提前进行过aop,那么还有一次从三层缓存中获取bean的过程,而此时就可以从二级缓存中获取到a的代理对象呀,然后最终返回
- 循环依赖 :我哭了呀,a、b这俩狗子牛啊牛啊打死☠️
到此是否明白了如下俩个问题呢?
- 为什么从三级缓存获取到代理对象后,要把此对象放入二级缓存?
答:存在循环依赖的bean在填充赋值完成后仍然是一个原始对象,虽然在被别的bean当作填充属性的时候会被aop,会被标记为一个提前暴露的对象,但是一套流程走下来仍然是一个原始对象呀,由于被标记了是一个提前暴露的bean,因此并不会在initializeBean这再次进行aop,所以我们获取bean的最后一步需要再次从三层缓存中获取一次bean(此时的二级缓存存在我们所需的代理对象),这样最终获取返回的bean就是一个代理对象了,然后把代理对象放入一级缓存。故放入二级缓存的目的即存在循环依赖正确的条件下正确返回代理对象 - 为什么从三级缓存获取到代理对象后,要移除三级缓存中的内容?
答:避免多次创建代理对象