当我们用注解或者xml中配置一个bean的时候,又或者当我们写增删改查的时候在类上使用@Service,@Component,@Controller这些注解时,这些对象在spring中是如何被创建出来的呢?稍微研究spring源码就会发现,spring在创建一个bean的时候分两类,单例bean和原型bean(多例),单例的bean会在spring启动的时候就完成创建,而多例bean在使用的时候才会创建,但大致流程基本一样,只是创建就时机不同。下面用一个demo结合源码分析一下spring的创建一个bean的完整流程,在创建bean的时候做了哪些事情。
demo演示
public class Main {
public static void main(String[] args) {
//ZTest1Config配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ZTest1Config.class);
A1 a1 = (A1)context.getBean("a1");
a1.ga1();
}
}
/**
* 注解配置类
*/
@Order(2)
@ComponentScan("org.test1.bean1")
@Configuration
public class ZTest1Config {
}
/**
* 注册的bean
*/
@Component("b1")
public class B1 {
}
一个简单的demo,大概意思就是把配置类交给spring,spring扫描配置类,获取类路劲下的bean,加入到spring容器。然后就可以调用getBean方法获取bean,调用相关方法。这是一套简单的流程,细节远不止于此。
创建bean的流程
首先介绍下spring的创建bean的流程,大致如下:
- 扫描指定路径下的类,解析并转化为BeanDefinition,放入bd的map中 (这里就是标注注解的哪些类)
- 遍历所有的bd,一个一个执行以下操作
- 验证,检查,标记,调用一些回调
- 推断构造方法
- 反射创建bean对象的实例
- 合并bd
- 放入三级缓存(可以解决循环依赖)
- 属性注入(@Autowired,@Value等注解注入的值)
- 执行bean的部分aware接口和所有定义的bean生命周期中初始化的回调方法,以及处理bean实现的后置处理器接口(如处理AOP)
- 注册销毁方法
- 放入单例池
扫描
单例bean的创建是spring启动过程中的一小部分,在启动的时候就完成了对spring bean的扫描,然后拿到扫描的bean进行创建的一系列操作。
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
public void refresh() throws BeansException, IllegalStateException {
....
//在这里完成了对类路径下的bean扫描,并将bean转为bd,放入到map
invokeBeanFactoryPostProcessors(beanFactory);
...
}
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
//这里执行的是spring内置的‘配置类后置处理器’ ConfigurationClassPostProcessor。
//这个配置类会扫描所有我们配置的类,并将bean包装成bean定义(beanDefinition)后注册到bean工厂
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors,registry,beanFactory.getApplicationStartup());
...
}
通过上述代码断点最后会发现,实际上真正执行扫描的是ConfigurationClassPostProcessor.processConfigBeanDefinitions()方法。
/**
* 真正的配置类的后置处理器的回调
* Build and validate a configuration model based on the registry of
* {@link Configuration} classes.
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//存放我们自己注入的配置文件类
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//这是的存的是spring内置的配置类 加上我们通过启动容器注入进来的配置类
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//检查配置类是否为我们自己加入的配置类(是否加了@Configuration注解),同时打上标记,然后再加入到候选的配置类集合当中
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
//如果没有找到相关的配置类的话,则直接返回
if (configCandidates.isEmpty()) {
return;
}
// 根据配置类的@Order注解排序,没有加的排到最后(Integer的最大值)
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 创建一个配置类解析器,准备解析
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//存放准备解析的配置类集合
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//存放已经解析过了的配置类集合
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
/*
* 这里开始解析 我们自己编码的配置类(即通过容器实例化时参数带入的类 new ApplicationTest1(ConfigTestAnno.class, ConfigTestAnno1.class);)
* 扫描我们指定包,并将扫描到的配置类加入到bean工厂
*
* node:这个方法会递归查找扫描到的配置类各种方式(如@import导入的,实现了ImportSelector接口导入的等等)导入的类,并绑定到相关的配置类上
*
* */
parser.parse(candidates);
/*
* 验证:这里验证的是上面解析的配置类中。
* 1.被@Configuration注解的配置类,如果代理模式为true,则该类不能被final修饰
* 2.被@Configuration注解的配置类中存在被@Bean注解标注的方法,该方法不能被 final,private,static修饰,目的是为了实现代理重写此方法
*
* */
parser.validate();
//存放解析出来的配置类集合(该集合的元素是等待注册到bean工厂的)
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
//移除已经解析的
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
/*
* 将解析的配置类中 配置的bean注入到bean工厂 (并不完全这是里bd)
* */
this.reader.loadBeanDefinitions(configClasses);
//将上一步已注册bean的集合加入 已解析集合
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
//我们第n个配置文件的配置类 内容已解析完毕,清空集合
candidates.clear();
//再次遍历,如果有没有解析到配置类,加入待解析集合再次解析
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
总之ConfigurationClassPostProcessor这个类完成了对我们配置路径下的bean完成了扫描,解析,并转化为bd放入对应的bd的map中,方便后续使用。具体的扫描和解析过程很繁琐,就不再展开。
遍历
上面已经对bean完成了扫描和解析,放入集合,那么spring需要拿到这个集合,遍历一个个的bd完成创建的操作。
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
public void refresh() throws BeansException, IllegalStateException {
....
/*
* 在这里完成bean工厂的初始化!
* 1.创建容器的单例池,在BeanDefinition中如果处于非懒加载的,单例的bean会在这里创建,这里就是spring的bean的生命周期。
* 2.添加字符串解析器
* 3.在实例化单例池之前,先初始化LoadTimeWeaverAware接口的实现类
* */
finishBeanFactoryInitialization(beanFactory);
...
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
...
/*
* 实例化剩下的非懒加载的单例bean
* */
beanFactory.preInstantiateSingletons();
...
}
从这一步开始,后面的过程都在beanFactory.preInstantiateSingletons()中方法完成。
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
/*
* 将所有的未实例化的单例bean放入一个新的集合。
* 目的是一批一批的实例化。之后新注册的bean,和此次实例化的互不影响
* */
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
/*
* 遍历所有的bean开始一个个实例化
*
* */
for (String beanName : beanNames) {
/*
* 实例化之前获取合并后的bean定义。
* 因为bean可能会存在父类的定义,父类定义里的属性子类会自动继承,合并的目的是为了将父子类的属性合并到一个bean定义中(属性可能会不一致),得到一个顶级的bean定义。
* */
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
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());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//我们自己配置的bean会直接进到这一步
// 单例bean的实例化
getBean(beanName);
}
}
}
....
}
通过遍历拿到bd,然后调用getBean()方法开始后实例化,这里的getBean和我们常用的getBean是同一个方法,只不过spring在这提前调用这个方法实例化单例的bean。而我们调用getBean的时候,如果是多例的那么在调用的那一刻就开始创建。
验证检查
这一步其实在spring创建bean的时候无处不在,创建前会检查一些东西,如class存不存在,依赖检查,bean名称统一。创建中,创建完成都会做一系列的检查,具体得看每一个步骤的代码。在这举例一二,如下:
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//确保Bean名称按照规范的方式进行转换。确保在容器中查找、注册和管理Bean时的一致性
String beanName = transformedBeanName(name);
Object beanInstance;
// Eagerly check singleton cache for manually registered singletons.
/*
* 检查单例池中是否存在该bean
* 包含早期的单例池,单例工厂,单例对象池
*
* */
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//如果没有,走正常逻辑
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
/*
* 如果这个bean正在创建,抛出异常。 此处异常多半是在循环依赖之中
*
* */
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
/*
* 检查父容器中检查是否存在bean
* */
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
/*
* 如果不是只读的,在这里标记bean正在创建
* 加入到正在创建的集合,并且如果是一个MergedDefinition,将其标记为需要重新合并,在merged持有者集合中删除
* */
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
/*
* 下面开始实例化bean
* */
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
/*
* 实例化前获取bean定义,如果bean定义是需要合并的,在这里会执行合并操作。
* 保证获取到bean定义是一个顶级的bean定义
* */
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
/*
* 检查上面的mbd是否为抽象的
* */
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
/*
* 依赖检查,初始化之前 需要先加载依赖.即处理XML配置文件中使用 <depends-on> 元素或在Java配置中使用 @DependsOn 注解
* */
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);
}
}
}
....
}
在上面doCreate方法的验证部分走完之后,单例的bean会进入自己的代码块,执行相关方法开始执行创建,在这部分代码还有很长的一部分的验证代码要走,到离推断构造方法还有一段距离
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
....
// Create bean instance.
if (mbd.isSingleton()) {
//new一个单例工厂,自己编写获取单例逻辑(创建一个单例,放入单例池)
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//回调自己的实例化bean的逻辑
return AbstractBeanFactory.this.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.
AbstractBeanFactory.this.destroySingleton(beanName);
throw ex;
}
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
....
}
代码进入到getSingleton方法中,还会进行一系列的验证,然后开始回调getObject(),执行crateBean
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
*
* 返回指定beanName的单例对象,如果不存在就创建
*
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
//加锁防止多线程同时创建
synchronized (this.singletonObjects) {
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加入到正在创建的集合,或在是否在排除项之中,不行则抛出异常
beforeSingletonCreation(beanName);
boolean newSingleton = false;
//记录创建时发生的异常
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
/*
* 通过单例工厂获取单例对象 单例工厂的回调,此处是此方法的调用者回调自己的逻辑
* */
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
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;
}
/*
* 不管是否完成了单例的创建,从正在创建的集合当中移除
* */
afterSingletonCreation(beanName);
}
/*加入到单例池当中*/
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
singletonObject = singletonFactory.getObject();就开始执行创建bean的回调
// Create bean instance.
if (mbd.isSingleton()) {
//new一个单例工厂,自己编写获取单例逻辑(创建一个单例,放入单例池)
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
//回调自己的实例化bean的逻辑
return AbstractBeanFactory.this.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.
AbstractBeanFactory.this.destroySingleton(beanName);
throw ex;
}
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
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;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
/*
* 即将初始化,确保类已经被加载
* */
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
//如果被加载的bean不是class,重新创建一个bd
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
//检查并准备方法重写父类的bd信息。会检查Bean定义中是否包含了要重写的方法
// ,通常是通过Spring的AOP功能或者通过XML配置文件中的 <lookup-method> 或 <replaced-method> 元素来定义
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
/*
* 实例化之前处理InstantiationAwareBeanPostProcessor的回调.
* 目的是给开发者可以自己实现此接口,自己手动创建一个完整的bean,不需要spring为我们创建bean。如果没有那表示默认spring创建
* */
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创建
* 1.在这创建对象,
* 2.属性填充,
* 3.调用初始化相关回调方法和
* 4.注册销毁方法。
* */
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
/*
* 至此,一个完整的bean创建完成。
* */
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
推断构造方法
在这里依然会验证,执行自定义回调,再调用doCreateBean,最后调用createBeanInstance推断构造方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/*
* 推断构造方法,创建了bean对象实例
* */
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
...
}
/*
* 这里创建bean的实例。spring中三种实例化bean的区分:
* 开发者自己实现的接口创建实例(实现Supplier接口,实现创建对象逻辑)
* 工厂方法创建实例(在配置类中使用@Bean注解返回的对象)
* 正常扫描到的(需要推断构造方法)
*
* */
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
/*
* 属于工厂方法创建
* */
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
/*
* 属于正常扫描的bean
* */
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
/*
* 下面开始推断构造函数:三步走
* 1.查找使用了@Autowrite注解的函数,如果有则走该逻辑的构造
* 2.如果没有,则看看是否bean定义中是否指定了构造函数,如果有则使用
* 3.以上都不行,则直接使用默认的无参构造函数
* */
/*
* 如何推断构造方法?:
* 所有的构造函数中是否有且仅有一个@Autowrited注解并且属性required=true的构造函数,如果有那么就是他。如果有多个@Autowrited注解的,那么required只能为false,则抛出异常
* 如果所有的构造函数没有@Autowrited注解,且又bean定义中又没有指定构造函数,那么必须是无参构造函数。否则抛出异常
* 有多个@Autowrited注解的构造函数,但是required=false的会加入到候选组集合返回(如果没有@Autowrited注解默认的无参构造也会加入集合),进一步推断
*
*
*
* */
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);从这段代码开始就表示要开始推断构造方法了,日常开发中我们基本上没有配置构造,所以基本上都是使用默认的构造,这个方法是获取所有的可候选的构造方法,即开发人员配置了@Autowrited注解的构造和默认构造从中筛选
/*
* 推断候选的构造方法:
* 1.检查所有的构造方法是否存在@Autowrited注解。
* 2.如果有@Autowrited注解的构造且required=true的,那么表示这是用户指定的构造方法,如果还有其他的方法加了@Autowrited注解的,直接抛出异常
* 3.如果没有@Autowrited注解且required=true的,那么检查是否存在@Autowrited注解required=false的,存在的话,如果还有默认的构造,有这两类则加入到候选组
* 4.符合上述条件的都会加入到候选组,没有则返回null
* */
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
/*
* 检查@Lookup注解。
* 单例bean依赖原型bean的是需要将原型bean转化为单例
* */
// Let's check for lookup methods here...
if (!this.lookupMethodsChecked.contains(beanName)) {
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class<?> targetClass = beanClass;
do {
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
this.lookupMethodsChecked.add(beanName);
}
/*
* 先检查候选缓存组,如果有,则表示之前已经推断过了,此时无需再做多余的动作,直接返回。
* */
// Quick check on the concurrent map first, with minimal locking.
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
//没有表示没有推断过,或者之前就没推断出来
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
//双重检查锁,防止重复多线程重复推断
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
//存放所有的构造方法
Constructor<?>[] rawCandidates;
try {
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
//存放候选的构造方法
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
//存放用户指定的构造方法:即@Autowrited注解为required=true的
Constructor<?> requiredConstructor = null;
//存放无参的默认构造
Constructor<?> defaultConstructor = null;
//获取Kotlin类,我们用不到,忽略
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
//表示所有的构造方法中,不是合成的构造方法有多少个(内部类时,可能会出现合成的构造,正常情况没有)
int nonSyntheticConstructors = 0;
//遍历所有的构造开始推断
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
//记录正常的构造方法的数量
nonSyntheticConstructors++;
}
//为空不管
else if (primaryConstructor != null) {
continue;
}
/*
* 查找构造方法中是否添加了@Autowrited注解
* */
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
//如果没有加,判断是不是cglib代理的类,如果是,那么找到开发者定义的类,根据参数去匹配真实类的构造并检查是否存在@Autowrited注解
Class<?> userClass = ClassUtils.getUserClass(beanClass);
//表示当前是代理类,需要查找真实的类构造的注解情况
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
//如果找到了@Autowrited注解
if (ann != null) {
/*
* requiredConstructor != null 说明之前的遍历中已经找到了用户指定的构造函数(@Autowrited:required=true的),
* 再次进入这个分支,说明开发者还配置了其他的构造函数@Autowrited注解,spring不允许这样配置,抛出异常
* */
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
boolean required = determineRequiredStatus(ann);
if (required) {
/*
* required为true且!candidates.isEmpty() ,同上,抛出异常
* */
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
}
//记录默认的无参构造
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
/*
* 找到一些候选的构造,且开发者没有指定那一个构造,那么也将无参构造加入候选组
* */
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
//封装为数组
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
//只有一个构造函数的,且不是无参构造
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//Kotlin相关,不考虑
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
//没有找到,返回空
else {
candidateConstructors = new Constructor<?>[0];
}
//放入缓存,后面无需再推断
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
这里要么有多个候选的构造,要么一个,要么没有。多个是最复杂的情况,只有一个的话那么就是他,没有就调用后面逻辑或者找无参构造。那么如果是多个的话,就会从多个中找到最符合条件的一个作为构造方法,具体查找方法如下:
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
//bean实例化的包装器
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
//存放要使用的构造函数
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
//存放要使用的构造函数的参数
Object[] argsToUse = null;
//如果已经指定了构造函数的参数,那么直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
//尝试从缓存中获取构造函数和参数
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//如果缓存的参数不为空,就开始解析参数
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//如果构造函数或参数不存在,那么说明继续推断
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
//如果没有候选的构造函数,那么直接找默认的无参构造
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
//是否允许非public的构造方法访问,然后根据反射获取公开或者非公开的构造
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
//如果只有一个候选构造,且没有参数,那么说明是默认的无参构造
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
//加锁设置缓存,有可能会再次解析或多线程解析。直接从缓存中取
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
//实例化bean
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
/*
* 没有默认的无参构造,那么需要继续推断构造函数
*
* autowiring为true表示自动注入,有@Autowried注解的构造,或者注入模型为AUTOWIRE_CONSTRUCTOR的就是自动注入
*
* minNrOfArgs记录需要的最少的参数值。有可能有多个候选构造,如果构造函数的参数小于这个值,那么肯定就不会是这个构造函数,直接跳过
* 如果开发者指定了参数,那么就是参数的个数就是该值,没有指定则为0
* */
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 对候选构造方法进行排序,public的方法排在最前面,都是public的情况下参数个数越多越靠前
AutowireUtils.sortConstructors(candidates);
/*
* 记录构造函数与参数的最小差异值:
* spring会排序遍历所有的构造函数,并且会去找构造函数上的参数,在寻找的过程中会记录每一个构造函数与参数的匹配程度,越匹配的这个差异值就越小
* */
int minTypeDiffWeight = Integer.MAX_VALUE;
/*
* 表示有歧义的构造函数,有可能多个构造函数的差异值一样,就不知道用那个构造函数了,就会放入该队列。再根据是否宽松或严格模式去判断,宽松则取第一个,严格则抛出异常
* */
Set<Constructor<?>> ambiguousConstructors = null;
//记录遍历时,程序抛出的异常
Deque<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
//经过多次遍历可能已经找到了需要的构造函数和参数,并且再比较找到的参数数量是否大于本次的,是的话那么后面的不需要再找了
// ,因为是排过序的,后面的参数数量只会小于本次的
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
//如果这个构造函数的参数小于最少需要的构造参数个数值,那么直接略过
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
/*
* 如果进入到了这里,说明开发者没有指定构造参数。
*
* 那么spring会根据每一个参数类型和名称到容器中取匹配合适的值
* */
if (resolvedValues != null) {
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//根据当前的构造函数,查找符合条件的参数
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
/*
* 如果指定了构造函数的参数,那么一直找到符合指定参数个数的构造函数,并创建一个参数持有器
* */
else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
/*
* 下面这段代码是计算构造函数与参数的差异化的值:
* 根据不同的模式(宽松/严格)计算最小差异值
* */
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
//此次计算的差异值比之前的更小,那么就取当前这个,然后重新赋值给minTypeDiffWeight,以便后续遍历使用
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;//这里复制为null,因为找到合适的了,之前即使有歧义的构造函数已经无所谓了
}
//计算出来差异值一样的多个函数表示存在歧义,加入到歧义队列。constructorToUse != null表示至少已经存在一个构造函数,因为两个及以上才会存在歧义
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
//如果没有推断出构造函数,则抛出异常
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
//严格模式下,不允许存在有歧义的构造函数
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
//如果开发者没有指定参数,且spring找到了参数,那么将参数缓存。(不会缓存开发者指定的参数,因为不知道何时开发者就会换掉指定的参数)
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
//实例化
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
总之,当一个Bean类存在多个可用的构造方法时,Spring会根据一定的规则来推断使用哪个构造方法进行实例化。主要的优先级规则如下:
- 使用参数数量最多的构造方法。Spring会优先选择参数最多的构造方法,以满足依赖注入的需要。
- 如果参数数量相同,使用索引参数最小的方法。例如参数类型为(int, String)会优先于(String, int)。
- 排除使用简单类型(primitives)的参数方法,优先选择对象或接口类型的参数。
- 使用@Autowired或@Value等注解标注的参数优先。
- 子类构造方法优先于父类方法。
- 优先选择不重复的参数类型。
- Java 8参数默认值支持后,含默认值的参数类型会排在最后。
反射创建bean对象
这一步就很直接, 根据上面推断符合的构造,拿到参数之后直接通过反射调用创建对象
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
合并bd
在创建完bean对象之后,再回到doCreate方法中,接着合并bd
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
....
/*
* 对象创建成功后,开始执行MergedBeanDefinitionPostProcessor的后置处理器
* */
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; //表示已经执行过了
}
}
....
}
applyMergedBeanDefinitionPostProcessors方法的主要逻辑:
- 获取所有已注册的MergedBeanDefinitionPostProcessor。
- 遍历这些post processor。
- 为每个post processor调用postProcessMergedBeanDefinition方法,传入参数为bean名称、bean类类型、bean定义。
- 如果任何一个post processor返回了非null的值,使用这个返回的bean定义,覆盖原有的。
这个方法为Bean定义合并后提供了扩展点,如果对spring进行扩展可用调用此方法
放入三级缓存
这里是为了解决循环依赖的一部分操作,怎么解决循环依赖又是spring一个大的部分,就不在详解
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
....
/*
* 将正在创建的单例对象,
* 加入单例工厂
* 加入到已经注册的集合
* 从早期的单例池中移除
* */
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}
....
}
属性注入
再创建完成bean之后,就需要对其中属性进行赋值了,如果是构造方法注入那么在推断构造方法时就已经注入了。
属性注入时会在spring中寻找对应的属性,如果存在就拿来用,如果不存在就会在bd容器中找,找到就开始创建。如果两个bean相互依赖那么就需要处理循环依赖。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
/*
* 这里自己可以自己实现InstantiationAwareBeanPostProcessors接口,用于修改bean的属性填充,如果返回false表示不需要spring后续填充
*
* */
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
/*
* 根据注入模型注入bean的属性。
* AUTOWIRE_BY_NAME 通过名称注入
* AUTOWIRE_BY_TYPE 通过类型注入
* AUTOWIRE_CONSTRUCTOR 通过构造函数注入
*
* 一般为AUTOWIRE_NO 表示没有注入模式
*
* */
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
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.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
/*
* 是否存在实现了InstantiationAwareBeanPostProcessor的处理器。初始化时这里为true,因为有spring自带的内置处理器实现了该接口
* 使用了@Autowire注解的属性注入就是在这里进行的(AutowiredAnnotationBeanPostProcessor处理器)
*
* @Resource:使用CommonAnnotationBeanPostProcessor后置处理器解析
@Autowired:使用AutowiredAnnotationBeanPostProceoor后置处理器解析
* */
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {//这里再次调用getPropertyValues()是为了给个默认值
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) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
执行相关回调接口
在属性注入完成之后就开始调用各种相关的回调接口,这也是pring提供的扩展点,方便了给开发者在bean实例化最后的阶段,对bean做一些额外的功能扩展,如执行生命周期的初始化方法,执行部分aware接口,配置有aop的执行aop代理
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
/*
* 执行部分aware接口
* */
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
/*
*
* 这里会执行spring的几种初始化的生命周期回调
* @PostConstruct,实现InitializingBean,自己配置的init-method。
*
* */
// 最先执行BeanPostProcessor的初始化方法,@PostConstruct注解方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 在这先后执行:
// 再执行实现InitializingBean接口的回调
// 最后执行自己配置的init-method。
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 还需要执行beanPostProcessor的after接口,可以修改bean的属性,spring提供的扩展 ,如果有AOP在这里进行
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
注册销毁方法,放入单例池
在执行完initializeBean之后,表明spring已经完成对bean的实例化,会再做一次循环依赖检查,注册销毁方法,在执行完doCreate方法之后,表示一个完整的单例的bean已经创建完成,最后会放入单例池
/**
*判断bean不是原型且需要销毁
*如果是单例,注册DisposableBeanAdapter到容器
*如果是自定义作用域,在作用域上注册销毁回调
*DisposableBeanAdapter会包装相关信息,并在销毁时调用销毁逻辑
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
// 如果bean不是原型模式且需要销毁
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// 如果是单例模式
if (mbd.isSingleton()) {
// 注册一个DisposableBeanAdapter来处理销毁逻辑
// 它会封装bean, beanName和destroy方法
// 并最终调用registerDisposableBean进行注册
registerDisposableBean(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
else {
// 自定义作用域的bean
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
// 在自定义作用域上注册销毁回调
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
}
}
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
....
/*加入到单例池当中*/
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
....
}
总结
以上就是spring创建一个bean的详细流程,主要流程包括缓存查找、实例化、初始化和销毁几部分,这整个流程确保了spring容器能够完整地管理bean的完整生命周期。