网站首页 > 技术教程 正文
spring IOC容器:
- xml配置形式定义bean信息
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 定义一个 Bean 的信息 -->
<bean id="car" class="com.demo.compent.Car"></bean>
</beans>
public static void main( String[] args ){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
System.out.println(ctx.getBean("person"));
}
- 基于配注解形式定义bean信息
@Configuration
public class MainConfig {
@Bean
public Person person(){
return new Person();
}
}
@Configuration
public class MainConfig {
//bean名称默认是方法名,若@Bean(value='bean名称') ,那么bean的名称就是指定的
@Bean
public Person person(){
return new Person();
}
}
往 IOC 容器中添加组件的方式:
- 通过注解@Import;
- 通过 自定义实现ImportSelector方法;
- 通过自定义实现ImportBeanDefinitionRegister方法
- 通过@@Component,@ComponentScan,@ComponentScans
public class MyImportSeletor implements ImportSelector {
/**
* @AnnotationMetadata 注解元数据 实现
* AnnotationMetadataReadingVisitor (基于asm实现,效率高但是代码难度大)
* StandardAnnotationMetadata(基于反射,简单但效率低)
* @param importingClassMetadata
* @return
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.demo.testimport.compent.MyCar"};
}
/**
* 需要排查的
* @return
*/
@Override
public Predicate<String> getExclusionFilter() {
return null;
}
}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
//创建一个 bean 定义对象
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(MyCar.class);
//把 bean 定义对象导入到容器中
registry.registerBeanDefinition("myCar",rootBeanDefinition);
registerBeanDefinitions(importingClassMetadata, registry);
}
}
通过 Spring 的 BeanPostProcessor 的 bean 的前后置处理器会拦截所有 bean 创建过程
/**
* 自定义BeanPostProcessor
* 所有的bean都会进入
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化之前操作");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化之后操作");
return bean;
}
}
假如我们自己的组件需要使用 ApplicationContext 等,我们可以通过实现 XXXAware 接口来实现
@Component
public class MyApplicationContextAware implements ApplicationContextAware,BeanNameAware {
/**
* BeanNameAware
* @param name
*/
@Override
public void setBeanName(String name) {
System.out.println("当前bean的名称是:"+name);
}
/**
* applicationContext操作
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
}
}
AbstractApplicationContext.addApplicationListener()//自定义注册事件
bean 实例化过程的调用链
i1:>org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
i2>org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
i2.1>:org.springframework.beans.factory.support.AbstractBeanFactory#transformedBeanName 转换beanName
i2.2>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton去 缓 存中获取 bean
i2.3>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance对缓存中的获取的 bean 进行后续处理
i2.4>:org.springframework.beans.factory.support.AbstractBeanFactory#isPrototypeCurrentlyInCreation判断原型 bean 的依赖注入
i2.5>:org.springframework.beans.factory.support.AbstractBeanFactory#getParentBeanFactory 检查父容器加载 bean
i2.6>:org.springframework.beans.factory.support.AbstractBeanFactory#getMergedLocalBeanDefinition将 bean 定义转为 RootBeanDifination
i2.7>:检查 bean 的依赖(bean 加载顺序的依赖)
i2.8>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton 根据scope 的添加来创建 bean
i3>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean 创建bean 的方法
i4>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 真 正的创建 bean 的逻辑
i4.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance 调用构造函数创建对象
i4.2>: 判 断 是 否 需 要 提 早 暴 露 对 象 (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
i4.3>org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory暴露对象解决循环依赖
i4.4>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean给创建的 bean 进行赋值
i4.5>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean对 bean 进行初始化
i4.5.1>:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods 调用 XXAware 接口i4.5.2>applyBeanPostProcessorsBeforeInitialization 调用 bean 的后置处理器进行对处理
i4.5.3>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods 对象的初始化方法
i4.5.3.1>:org.springframework.beans.factory.InitializingBean#afterPropertiesSet
调用InitializingBean 的方法
i4.5.3.2>:String initMethodName = mbd.getInitMethodName(); 自定义的初始化方法
i5>:org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton 把创建好的实 例化好的 bean 加载缓存中
i6>:org.springframework.beans.factory.support.AbstractBeanFactory#getObjectForBeanInstance 对创建的 bean 进行后续的加
bean初始化源码解析
//bean初始化
//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//调用 bean 实现的 XXXAware 接口
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用 bean 的后置处理器的 before 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用 initianlBean 的方法和自定义的 init 方法
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 的后置处理器的 post 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
返回指定bean
/**
* 返回指定bean的实例
* org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
*/
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
/*** 转换对应的 beanName 你们可能认为传入进来的 name 不就是 beanName 么?
* 传入进来的可能是别名,也有可能是是 factoryBean
* 1)去除 factoryBean 的修饰符 name="&instA"=====>instA
* 2)取指定的 alias 所表示的最终 beanName 比如传入的是别名为 ia---->指向为 instA 的 bean,那么就返 回 instA
* **/
String beanName = transformedBeanName(name);
Object beanInstance;
/*** 设计的精髓 * 检查实例缓存中对象工厂缓存中是包含对象(从这里返回的可能是实例话好的,也有可能是没有实例 化好的)
* 为什么要这段代码? 因为单实例 bean 创建可能存主依赖注入的情况,而为了解决循环依赖问题,在对象刚刚创建好(属性 还没有赋值)
* 的时候,就会把对象包装为一个对象工厂暴露出去(加入到对象工厂缓存中),一但下一个 bean 要依赖 他,就直接可以从缓存中获
*/
//为手动注册的单例对象检查单例缓存。判断是否为单例对象
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//返回单例对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
/*** 为什么 spring 对原型对象就不能解决循环依赖的问题了?
* 因为 spring ioc 对原型对象不进行缓存,所以无法提前暴露对象,每次调用都会创建新的对象.
* 比如对象 A 中的属性对象 B,对象 B 中有属性 A, 在创建 A 的时候 检查到依赖对象 B,那么就会 返过来创建对象 B,在创建
* 又发现依赖对象 A,由于是原型对象的,ioc 容器是不会对实例进行缓存的 所以无法解决循环依赖 的问题
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
///获取父类工厂bean
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//如果 beanDefinitionMap 中所有以及加载的 bean 不包含 本次加载的 beanName,那么尝试取父容 器取检测
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
//如果这里不是做类型检查,而是创建 bean,这里需要标记一下.
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
//合并父 BeanDefinition 与子 BeanDefinition,后面会单独分析这个方法
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//用来处理 bean 加载的顺序依赖 比如要创建 instA 的情况下 必须需要先创建 instB
/*** <bean id="beanA" class="BeanA" depends-on="beanB">
* <bean id="beanB" class="BeanB" depends-on="beanA">
* 创建 A 之前 需要创建 B 创建 B 之前需要创建 A 就会抛出异常 * */
String[] dependsOn = mbd.getDependsOn();
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 {
//优先创建依赖的对象
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建 bean(单例的 )
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//创建非单实例 bean
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = 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 = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
创建的bean进行赋值
/**
* 1)获取了 bw 的属性列表
* 2)在属性列表中被填充的之前,通过 InstantiationAwareBeanPostProcessor 对 bw 的属性进行修改
* 3)判断自动装配模型来判断是调用 byTypeh 还是 byName
* 4)再次应用后置处理,用于动态修改属性列表 pvs 的内容
* 5)把属性设置到 bw 中
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
//若 bw 为空的话 ,那么为 bw 的属性去赋值将没有任何意思
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
return;
}
}
/** 在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改
* bean 状态的机会。官方的解释是:让用户可以自定义属性注入。比如用户实现一
* 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
* postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。
* 当时我们发现系统中的的 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiationM
* 没有进行 任何处理,
* 若我们自己实现了这个接口 可以自定义处理.....spring 留给我们自己扩展接口的
* 特殊需求,直接使用配置中的信息注入即可。
* 已经通过自己写的 InstantiationAwareBeanPostProcessor 类型的处理器已经设 置过 bean 的属性值 直接return
*/
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
/* 判断注入模型是不是 byName 或者是 byType 的 */
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//按照名称自动给装配的bean
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//按照类型自动给装配的bean
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
/** * 判断有没有 InstantiationAwareBeanPostProcessors 类型的处理器 ** */
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
/*** 判断是否需要依赖检查(默认是 0)
* DEPENDENCY_CHECK_NONE(0) 不做检查
* DEPENDENCY_CHECK_OBJECTS(1) 只检查对象引用
* DEPENDENCY_CHECK_SIMPLE(2)检查简单属性
* DEPENDENCY_CHECK_ALL(3)检查所有的 * */
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
/** 这里又是一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理,
* 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了,
* 而是经过后置处理器修改后的内容 */
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//通过后置处理器来修改属性
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
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) {
//设置属性到 beanWapper 中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
初始自定义invokeAware方法源码
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
* 调用 XXAware 接口
* @param beanName
* @param bean
*/
private void invokeAwareMethods(String beanName, Object bean) {
//判断 bean 是否实现了 Aware 接口
if (bean instanceof Aware) {
//实现了 BeanNameAware 接口
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
//实现了 BeanClassLoaderAware 接口
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//实现了 BeanFactoryAware 接口
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
bean初始化方法
/**
* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
* 对 象 的初始化方法
* @param beanName
* @param bean
* @param mbd
* @throws Throwable
*/
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
////判断你的 bean 是否实现了 InitializingBean 接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
//调用了 InitializingBean 的 afterPropertiesSet()方法
((InitializingBean) bean).afterPropertiesSet();
}
//调用自己在配置 bean 的时候指定的初始化方法
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
//配置的初始化方法是否为默认方法
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// 忽略不存在的bean
return;
}
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
try {
//method.setAccessible(true);设置可见性
ReflectionUtils.makeAccessible(methodToInvoke);
//执行方法调用
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
把创建好的bean放入缓存
/**
* 将给定的单例对象添加到该工厂的单例缓存中。三级缓存,解决循环依赖问题
单例对象的缓存:bean名称到bean实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
单例工厂缓存bean
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
早期单例对象的缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
注册的单例集合,包含注册顺序的bean名称
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
* @param beanName
* @param singletonObject
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
bean的创建及循环依赖解决
/**
* 创建bean并解决循环依赖(单例模式下)
* @param beanName
* @param mbd
* @param args
* @return
* @throws BeanCreationException
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
//判断是否为单例模式
if (mbd.isSingleton()) {
//删除工厂缓存的bean
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//如果为空创建一个实例化对象
/** * 如果存在工厂方法则使用工厂方法进行初始化
一个类有多个构造函数,每个构造函数都有不同的参数,
所以需要根据参数锁定构造 函数并进行 初始化。
如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行 bean 的实例 化
* */
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//允许后处理器修改合并的bean定义
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;
}
}
//singletonsCurrentlyInCreation.get() 判断是否正常创建的bean
//指定的单例bean是否正在创建中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//添加bean到缓存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//bean初始化赋值
populateBean(beanName, mbd, instanceWrapper);
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);
}
}
if (earlySingletonExposure) {
//*返回在给定名称下注册的(原始)单例对象。
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
// allowRawInjectionDespiteWrapping 是否在循环引用的情况下使用注入生bean实例,
//hasDependentBean 确定是否为指定的名称注册了依赖bean
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.");
}
}
}
}
try {
/**
*将给定的bean添加到工厂的一次性bean列表中,
*注册它的DisposableBean接口和/或给定的destroy方法
*工厂关闭时调用(如适用)。只适用于单例
*/
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
/**
* 获取单例bean对象
* @param beanName bean名称
* @param allowEarlyReference 是否应该创建早期引用
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
/**
*
// 单例对象的缓存:bean名称到bean实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 单例工厂缓存bean
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//早期单例对象的缓存
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
//注册的单例集合,包含注册顺序的bean名称
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
*/
//去缓存 map 中获取以及实例化好的 bean 对象
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//缓存中没有获取到,并且当前 bean 是否在正在创建
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//加锁,防止并发创建
synchronized (this.singletonObjects) {
//去缓存 map 中获取以及实例化好的 bean 对象
singletonObject = this.singletonObjects.get(beanName);
//早期对象缓存没有
if (singletonObject == null) {
//保存早期对象缓存中是否有该对象
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
//早期对象暴露工厂缓存(用来解决循环依赖的)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用方法获早期对象
singletonObject = singletonFactory.getObject();
//放入到早期对象缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
猜你喜欢
- 2024-10-19 Java 项目编译提示 javax.xml.bind.annotation does not exist 错误
- 2024-10-19 Android annotation包下常用的注解
- 2024-10-19 SpringMVC疑难一:mvc:annotation-dr
- 2024-10-19 Spring 中 AnnotationConfigUtils
- 2024-10-19 spring mvc 配置失效了?(springmvc的配置)
- 2024-10-19 为什么都爱着江南?黛瓦白墙,烟雨朦胧,是文人魂牵梦绕的故乡
- 2024-10-19 Spring框架系列之构造方法底层剖析01
- 2024-10-19 基于.NET6包含DDD,ES,CQRS等概念的开源
- 2024-10-19 spring 中 AnnotationUtils 的常用方法
- 2024-10-19 SpringBoot实战4-Spring基础-IoC容器
你 发表评论:
欢迎- 最近发表
-
- Win11学院:如何在Windows 11上使用WSL安装Ubuntu
- linux移植(Linux移植freemodbus)
- 独家解读:Win10预览版9879为何无法识别硬盘
- 基于Linux系统的本地Yum源搭建与配置(ISO方式、RPM方式)
- Docker镜像瘦身(docker 减小镜像大小)
- 在linux上安装ollama(linux安装locale)
- 渗透测试系统Kali推出Docker镜像(kali linux渗透测试技术详解pdf)
- Linux环境中部署Harbor私有镜像仓库
- linux之间传文件命令之Rsync傻瓜式教程
- 解决ollama在linux中安装或升级时,通过国内镜像缩短安装时长
- 标签列表
-
- 下划线是什么 (87)
- 精美网站 (58)
- qq登录界面 (90)
- nginx 命令 (82)
- nginx .http (73)
- nginx lua (70)
- nginx 重定向 (68)
- Nginx超时 (65)
- nginx 监控 (57)
- odbc (59)
- rar密码破解工具 (62)
- annotation (71)
- 红黑树 (57)
- 智力题 (62)
- php空间申请 (61)
- 按键精灵 注册码 (69)
- 软件测试报告 (59)
- ntcreatefile (64)
- 闪动文字 (56)
- guid (66)
- abap (63)
- mpeg 2 (65)
- column (63)
- dreamweaver教程 (57)
- excel行列转换 (56)
本文暂时没有评论,来添加一个吧(●'◡'●)