BeanFactory
BeanFactory是用于访问Spring Bean容器的根接口,典型的工厂模式,用于生产Bean的一个Bean工厂,其提供了生产Bean所需的最基本规则。
BeanFactory和FactoryBean区别:
BeanFactory用于生产Bean的一个Bean工厂
FactoryBean类是SpringIOC容器是创建Bean的一种形式,是对Bean的一个扩展点,可以通过implements FactoryBean来使用,它自身是一个Bean,可以使自身这个Bean可以生成其他的Bean,类似于工厂模式,而且这个生成Bean的逻辑可以通过重写getObject()方法由自己来控制。如果需要获取由FactoryBean创建出的Bean对象,通过Bean的名称可以直接获取到,如果需要获取到工厂Bean本身,需要在beanName前面添加&符号,加多少个无所谓,只要以&开头即可。
BeanDefinition
BeanDefinition是bean在spring中的描述(Bean图纸),它是顶级基础接口,用来描述Bean,里面存放Bean元数据,比如Bean类名、scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是懒加载等一些列信息。
向上接口:
BeanMetadataElement接口:BeanDefinition元数据,返回该Bean的来源
AttributeAccessor接口:提供对BeanDefinition属性操作能力
向下接口:
AbstractBeanDefinition类:抽象类,统一实现了BeanDefinition定义的一部分操作,可以说是定义了BeanDefinition很多默认的属性。 在AbstractBeanDefinition基础上, Spring衍生出了一些列BeaDefinition。
重要接口、类
BeanDefinitionRegistry接口:具有增,查,删BeanDefinition的能力。一次只能注册一个BeanDefinition,一般实现类里都都有一个 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap()来存储BeanDefinition.
BeanDefinitionReader接口: 既可以使用BeanDefinitionRegistry构造。也可以通过loadBeanDefinitions把配置加载为多个BeanDefinition并注册到BeanDefinitionRegistry中。 是高效版本的BeanDefinitionRegistry,实现类有:
XmlBeanDefinitionReader:从xml中读取BeanDefinition
PropertiesBeanDefinitionReader:从Properties文件读取BeanDefinition
AnnotatedBeanDefinitionReader类:注册了很多后置处理器,并对带有注解的BeanDefinition进行注册。
ClassPathBeanDefinitionScanner类:可以扫描到@Component @Repository @Service @Controller 的BeanDefinition注册到容器中。
方法解释
String: getBeanClassName: 返回当前bean definition定义的类名
ConstructorArgumentValues: getConstructorArgumentValues:返回bean的构造函数参数
String[]: getDependsOn:返回当前bean所依赖的其他bean的名称
String: getFactoryBeanName: 返回factory bean的名称
String: getFactoryMethodName: 返回工厂方法的名称
BeanDefinition: getOriginatingBeanDefinition: 返回原始的BeanDefinition,如果不存在返回null
String: getParentName: 返回当前bean definition的父definition的名字
MutablePropertyValues: getPropertyValues: 返回一个用于新的bean实例上的属性值
String: getScope: 返回当前bean的目标范围
boolean: isAbstract: 当前bean是否是abstract,意味着不能被实例化
boolean: isLazyInit: bean是否是延迟初始化
boolean: isPrimary: bean是否为自动装配的主要候选bean
boolean: isPrototype: bean是否是多实例
boolean: isSingleton: bean是否是单例
void: setAutowiredCandidate(boolean): 设置bean是否对其他bean是自动装配的候选bean
void: setBeanClassName(String): 指定bean definition的类名
void: setDependsOn(String ...): 设置当前bean初始化所依赖的beans的名称
void: setFactoryBeanName(String): 如果factory bean的名称
void: setFactoryMethodName(String): 设置工厂的方法名
void: setLazyInit(boolean lazyInit): 设置是否延迟初始化
void: setParentName(String): 设置父definition的名称
void: setPrimary(boolean): 设置是否主要的候选bean
void: setScope(String): 设置bean的范围,如:单例,多实例
AnnotationConfigApplicationContext结构关系
Spring IOC容器的加载过程
//创建AnnotationConfigApplicationContext对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
//根据参数类型可以知道,可以传入多个annotatedClasses
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//初始化BeanFactory,Bean读取器,Bean扫描器
this();
//注册配置类到BeanDefinitionMap中
register(annotatedClasses);
//刷新IOC容器(核心方法)
refresh();
}
this()方法中有三步操作:
1、调用本类无参构造函数,会先调用父类GenericApplicationContext的构造函数,初始化DefaultListableBeanFactory,并且赋值给BeanFactory
2、本类的构造函数里面,初始化了一个读取器:AnnotatedBeanDefinitionReader reader,Reader中注册了很多后置处理器,比如ConfigurationClassPostProcessor,在这个类中,会读取到加了@Configuration的配置类(加了这个注解的话,会为配置类创建cglib动态代理,保证每次都去单例池里拿,而不是重复加载),还会读到@ComponentScan、@ComponentScans注解扫描的包,以及@Import@Bean等注解,是用来解析配置类的处理器。还有AutowiredAnnotationBeanPostProcessor,用于读取@Autowired注入的类。还注册了很多其他用于解析注解的Bean定义。后续通过调用invokeBeanFactoryPostProcessors解析注册过的配置
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
//把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
this.registry = registry;
//用户处理条件注解 @Conditional os.name
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//注册一些内置的后置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
3、还有一个扫描器ClassPathBeanDefinitionScanner scanner,此处scanner实例不作为配置类中的扫描实例,此实例是给单独提供给ApplicationContext去扫描包的,不参与配置类的扫描(解析配置类时会new一个scanner对象进行扫描),我们可以传入构造参数时为空,不指定配置类,然后调用scan方法手动去扫描包。
refresh()方法:
IOC加载过程中最主要的是invokeBeanFactoryPostProcessors、finishBeanFactoryInitialization
两个方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//准备刷新上下文环境
prepareRefresh();
//获取告诉子类初始化Bean工厂 不同工厂不同实现
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//对bean工厂进行填充属性
prepareBeanFactory(beanFactory);
try {
//留个子类去实现该接口
postProcessBeanFactory(beanFactory);
//将class扫描成beanDefinition,调用Bean工厂的后置处理器,解析注册过的配置类,注册Bean定义
invokeBeanFactoryPostProcessors(beanFactory);
//注册Bean的后置处理器
registerBeanPostProcessors(beanFactory);
//初始化国际化资源处理器.
initMessageSource();
//创建事件多播器
initApplicationEventMulticaster();
//这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
onRefresh();
//把事件监听器注册到多播器上
registerListeners();
//实例化单例Bean.
finishBeanFactoryInitialization(beanFactory);
//最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
finishBeanFactoryInitialization方法:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 为我们的bean工厂创建类型转化器 Convert
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
//处理Aspect
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
//冻结所有的bean定义,注册的bean定义将不被修改或任何进一步的处理
beanFactory.freezeConfiguration();
//实例化剩余的单实例bean
beanFactory.preInstantiateSingletons();
}
preInstantiateSingletons方法:
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
//获取容器中所有Bean定义的名称(包括通过ComponentScan扫描到的、@Bean注入的等)
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//循环所有的Bean定义名称
for (String beanName : beanNames) {
//合并不同类型的Bean定义,转换为统一的RootBeanDefinition类型,方便后续处理
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//根据Bean定义判断:不是抽象的 && 是单例的 && 不是懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断是不是FactoryBean(是否实现了FactoryBean接口)
if (isFactoryBean(beanName)) {
// 是工厂Bean会先生成实际的Beab,beanName是用来获取实Bean的
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//getBean(工厂Bean)
if (isEagerInit) {
getBean(beanName);
}
}
}
else {//非工厂Bean
getBean(beanName);
}
}
}
//到这里所有的单实例的Bean已经记录到单实例Bean到缓存池中
for (String beanName : beanNames) {
//从单例缓存池中获取所有的对象
Object singletonInstance = getSingleton(beanName);
//判断当前的Bean是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
//触发实例化之后的方法afterSingletonsInstantiated
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
doGetBean方法:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//传入进来的name可能是别名, 也有可能是工厂bean的name,转换成真实的name
final String beanName = transformedBeanName(name);
Object bean;
//尝试去缓存中获取对象
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。
//如果是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的bean 实例。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//判断AbstractBeanFacotry工厂是否有父工厂,一般情况下,只有Spring 和SpringMvc整合的时才会有父子容器的概念
//比如我们的Controller中注入Service的时候,发现我们依赖的是一个引用对象,那么他就会调用getBean去把service找出来
//当前所在的容器如果是web子容器,那么就会先去父容器找
BeanFactory parentBeanFactory = getParentBeanFactory();
//若存在父工厂,并且当前的bean工厂不存在当前的bean定义,那么bean定义就存在于父beanFacotry中
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取bean的原始名称
String nameToLookup = originalBeanName(name);
//如果为 AbstractBeanFactory 类型,委托父类处理
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//委托给构造函数 getBean() 处理
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
//委托给普通的 getBean() 处理
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查当前创建的bean定义是不是抽象的bean定义
checkMergedBeanDefinition(mbd, beanName, args);
//依赖bean的名称
String[] dependsOn = mbd.getDependsOn();
//判断是不是dependsOn的bean
//@dependsOn可以指定某个bean再另一个bean之前完成实例化
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
//获取depentceOn的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建单例bean
if (mbd.isSingleton()) {
//把beanName 和一个singletonFactory 并且传入一个回调对象用于回调
//添加bean到singletonsCurrentlyInCreation中,标记为正在创建
sharedInstance = getSingleton(beanName, () -> {
try {
//进入创建bean的逻辑
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//创建多例bean
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//省略后续代码......
return (T) bean;
}
createBean方法:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 确保此时的bean已经被解析了
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
//验证和准备覆盖方法( 仅在XML方式中)
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//第1个bean后置处理器
//通过bean的后置处理器来进行后置处理生成代理对象
//这里不会生成代理对象,只会解析的aop切面信息进行缓存
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
//返回后置处理器处理后的bean
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.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
doCreateBean方法:
对bean进行实例化(createBeanInstance)、填充属性(populateBean)、初始化(initializeBean)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//从没有完成的FactoryBean中移除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean的实例化对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//从beanWrapper中获取我们的早期对象
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//进行后置处理 @AutoWired @Value的注解的预解析
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.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//把早期对象包装成一个singletonFactory对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
//对属性进行赋值(@Autowired、@Value)
populateBean(beanName, mbd, instanceWrapper);
//进行对象初始化操作(调用后置处理器,执行AOP所以可能生成代理对象)
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);
}
}
//省略部分代码......
try {
//注册销毁的bean的销毁接口
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
IOC加载过程总结:
首先通过new AnnotationConfigApplicationContext构造一个ApplicationContext
1、这个构造方法中会实例化BeanDefinitionReader,Reader中注册了很多后置处理器,比如ConfigurationClassPostProcessor类,在这个类中,会读取到加了@Configuration的配置类,还会读到@ComponentScan、@ComponentScans注解扫描的包,以及@Import@Bean等注解。还有AutowiredAnnotationBeanPostProcessor等,用于读取@Autowired注入的类。以及很多其他核心类。
2、还有一个扫描器BeanDefinitionScanner ,这个scanner实例是给单独提供给applicationContext去扫描包的,可以通过这个scanner手动扫描包。
3、再通过BeanDefinitionRegistry注册配置类,此时配置类还没有解析成Bean定义,只是把解析需要的一些类进行了初始化。
4、在refresh()方法中,invokeBeanFactoryPostProcessors方法会把class扫描成beanDefinition,调用Bean工厂的后置处理器,解析注册过的配置类,注册Bean定义到BeanDefinitionMap中
5、然后在finishBeanFactoryInitialization方法中,会调用preInstantiateSingletons方法,这个方法中会判断是否符合生产标准(不是抽象的 && 是单例的 && 不是懒加载的),再判断是否是FactoryBean,区分工厂bean和非工厂bean来分别调用getBean()方法;
6、getBean会调用doGetBean方法,在doGetBean中会先从一级缓存中拿,拿到了就返回,拿不到就调用createBean方法,
7、createBean会第一次调用Bean的后置处理器,通过后置处理器可以阻止Bean的创建,这里可以解析Aop切面信息进行缓存
8、最后调用doCreateBean方法,真正的创建Bean的实例对象,在进行实例化(createBeanInstance)、填充属性(populateBean)、初始化(initializeBean)后最终把Bean放入一级缓存
Bean的生命周期:
总体可以分为六个阶段Bean定义、实例化、属性赋值、初始化、生存期、销毁
Bean定义
:BeanFactoryPostProcessors会解析BeanDefinitionReader注册过的配置类,并且注册解析完成的Bean定义到BeanDefinitionMap中。
实例化
:这个时候Bean的对象是最原始的,基本的属性还没有设置。
属性赋值
:然后填充属性,做完这一步,Bean象基本是完整的了,@Autowired@Value注解已经解析完毕,依赖注入完成。
初始化
:检查Bean实现的Awareness接口,根据不同实现接口调用不同的初始化方法,然后还会检查三种初始化回调方法,执行顺序为:
1、@PostConstruct注解标记的初始化方法
2、实现InitializingBean接口,重写了afterPropertiesSet的方法
3、xml中,bean标签里配置init-mothod属性,class中指定的方法。
生存期
:这时候的Bean已经被准备就绪了,会一直停留在应用的上下文中,直到被销毁;
销毁
:单例Bean的应用的上下文被销毁,在销毁之前会检查并调用:
1、@PreDestroy注释标注的回调方法
2、Bean实现了DisposableBean接口的话,调用destroy()方法
3、还有XML中,Bean定义包含destroy-method或@Bean(destroyMethod="…")指定的方法
什么是Spring应用上下文:
是对Spring容器的一种抽象化描述,Spring的核心是容器,容器并不唯一,大概分为两类:
一种是BeanFactory,是最简单的容器,只能提供基本的DI功能
还有一种就是继承了BeanFactory派生出来的应用上下文,ApplicationContext这些应用上下文的高级接口。对于上下文抽象接口,Spring也提供了多种类型的容器实现:
1、AnnotationConfigApplicationContext:从一个或多个基于java的配置类中加载上下文定义,适用于java注解的方式;
2、ClassPathXmlApplicationContext:从类路径下的一个或多个xml配置文件中加载上下文定义,适用于xml配置的方式;
3、FileSystemXmlApplicationContext:从文件系统下的一个或多个xml配置文件中加载上下文定义,也就是说系统盘符中加载xml配置文件;
4、AnnotationConfigWebApplicationContext:专门为web应用准备的,适用于注解方式;
5、XmlWebApplicationContext:从web应用下的一个或多个xml配置文件加载上下文定义,适用于xml配置方式。
BeanFactoryPostProcessors后置处理器执行流程:
1、new AnnotationConfigApplicationContext 时,会在AnnotatedBeanDefinitionReader中注册一个ConfigurationClassPostProcessor,这个是用来解析配置类的Bean工厂后置处理器。
2、在register()方法中把配置类注册到BeanDefinitionMap中。
3、在refresh()方法中的invokeBeanFactoryPostProcessors()方法中会调用所有类型是BeanDefinitionRegistryPostProcessor的bean定义,也就是拿到了ConfigurationClassPostProcessor的bean定义(此时BeanDefinitionMap中的bean定义只有ConfigurationClassPostProcessor是Registry类型的),调用getBean进行实例化。
4、然后调用ConfigurationClassPostProcessor中的processConfigBeanDefinitions方法,在这里会判断是否是完全配置类是不完全配置类(所有的带有@Configuration、@Bean、@Component、@import等注解的都会被认为是配置类,带有@Configuration的会是完全配置类,会为其创建cglib动态代理,防止bean重复加载),然后拿到所有配置类,因为现在BeanDefinitionMap中只有完全配置类,所以会拿到所有的完全配置类。
5、然后会new一个ConfigurationClassParser配置类解析器,通过parse()方法进行解析,首先会判断是否是通过@import导入进来的配置类,然后调用doProcessConfigurationClass()进行真正的配置类解析。
6、在doProcessConfigurationClass()中会先处理@propertySource注解(指定XML配置),然后拿到@ComponentScan 的所有属性,对属性中配置的包进行循环扫描,循环中会判断是不是@ComponentScan的配置中需要过滤或包含,并且不是接口的bean(Mybatis重写了判断接口的方法,所以xml才可以被扫描到)。
7、最后调用doScan,把包路径转换为物理资源路径(. -> /),并且拿到路径下所有的.class文件,把这些bean解析成Bean定义,通过BeanDefinitionRegistry注册到BeanDefinitionMap中(通过scanner扫描到的重复的beanName会报错,但是通过@bean注入的重复的bean会覆盖)。
循环依赖问题:
现有两个对象A、B,A为AOP对象,A依赖B,B依赖A,A先开始创建。
1、首先读取BeanDefinition,先读到了A、所以先调用A的getBean()方法,会先从一级缓存中尝试拿对象,如果拿到了就直接返回,但此时一级缓存是没有的,并且A也不是正在创建的状态。然后会把A放到一个set里,这个set就是标记A对象是一个正在创建的对象,并且实例化A,然后创建一个A的函数接口存储到三级缓存中。
2、然后解析A,对A进行属性赋值,就会读到@Autowired注入的B,此时就会递归去调用getBean(),开始创建B,同样也是先从一集缓存中拿B,没拿到,并且B也不是正在创建的状态。然后把B也放进set,标记成正在创建,并且实例化B,然后创建一个B的函数接口存储到三级缓存中,此时A、B都是正在创建的状态。
3、然后解析B,就读到了@Autowired注入的A,再递归调用getBean去拿A,还是会先从一级缓存拿,仍然没拿到,但此时A是正在创建状态,就表示是在循环依赖,就会去二级缓存拿,二级缓存也没有,再从三级缓存拿,三级缓存会先调用之前存储的A的函数接口,判断A是否要创建AOP对象,如果需要就创建AOP对象返回,没有就返回原实例对象,A是,所以会创建并且把代理后的A放到二级缓存中(此时放到二级缓存中也可以解决复杂循环依赖下重复创建AOP对象的问题,比如A依赖B,B依赖A,C也依赖A,A被依赖两次,放到二级缓存中就不会创建两次AOP对象了)。
4、此时B就拿到了A的实例化对象,然后通过反射,把B中的A完成属性赋值,然后完成B的初始化,把B放到一级缓存里。
5、B创建完后返回给A,因为此时A是一个新的AOP对象,所以还要去二级缓存中拿到代理对象赋给当前的A实例,然后完成初始化,最后把二级缓存中的BeanA放入到一级缓存,并且删除二级和三级缓存中的beanA,Bean创建完成。
总结:
其实在单线程下,一级缓存就能解决循环依赖问题,但是多线程下就可能会导致另一个需要依赖A的Bean拿到不完成整的bean。
所以就用二级缓存+锁来解决,把整个创建过程和从二三级缓存获取bean的时候加两把锁,例如T1创建A时,会先从一级缓存获取,然后在获取二级缓存的时候加锁,此时如果T2线程进来拿A的实例就会先获取一级缓存,没有获取到就阻塞在获取二级缓存之前。A创建完成之后会删除二三级缓存中的实例,所以此时只有一级缓存中有A对象。T2此时获取到锁,但是拿不到A,就会继续走创建流程,但在创建之前会再次从一级缓存中获取A对象,因为此时A已经在一级缓存中了,所以获取成功,通过这种双重校验机制,保证了Bean不会重复创建。
而三级缓存是为了确保只在循环依赖情况下,提前创建AOP对象。因为普通对象会在初始化后通过Bean的后置处理器创建AOP对象,如果A对象是一个需要AOP的对象,如果是初始化后再创建代理对象,在B注入A时,A就不是一个代理对象了,所以需要提前创建。三级缓存中不存储bean的实例,而是存储每个Bean绑定的函数接口,通过这个接口去创建该BeanAOP对象。其实如果在实例化之后就创建AOP对象然后把AOP对象放到二级缓存中,只使用二级缓存就能解决循环依赖下AOP的问题。三级缓存其实就是为了保证代码的单一职责性,用来解偶才衍生出来的。