补充:关于扫描的逻辑
/**
* Scan the class path for candidate components.
* @param basePackage the package to check for annotated classes
* @return a corresponding Set of autodetected bean definitions
*/
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage); // 大部分情况是这一种
}
}
其中大部分情况是下面一种。上面这种的componentsIndex是为了提高扫描效率
当配置了spring.components文件(文件内容不为空),才会走上面的componentsIndex逻辑。
spring.components文件内容示例:(相当于告诉Spring要去扫描哪些Bean)
com.gax.service.UserService=org.springframework.stereotype.Component
#com.gax.service.OrderService=org.springframework.stereotype.Component
注意:以上配置的类上面仍然需要添加@Component,不添加会报Bean找不到的异常
实例化非懒加载的单例Bean源码:
// 遍历、合并、创建非懒加载单例Bean
@Override
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.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 获取合并后的BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非懒加载的单例Bean,注意这里是抽象的BeanDefinition,和抽象类区分开
// <bean id='user' class='' abstract='true' scope='prototype'> 抽象的BeanDefinition
// 抽象的BeanDefinition不能生成Bean,但是可以给其他Bean当父BeanDefinition
// <bean id='userService' class='' parent='user'>
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 获取FactoryBean对象
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) {
// 创建真正的Bean对象(getObject()返回的对象)
getBean(beanName);
}
}
}
else {
// 创建Bean对象
getBean(beanName);
}
}
}
// 所有的非懒加载单例Bean都创建完了后
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = 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((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
注意:抽象的BeanDefinition和抽象类的区别。思考抽象的BeanDefinition有什么用?
getMergedLocalBeanDefinition合并BeanDefinition是什么意思?
这个方法非常重要,合并之后的BeanDefinition。合并属性等信息:自己定义了用自己的,自己没定义用父亲的
对于父子BeanDefinition,合并是生成一个新的BeanDefinition,原来的父子BeanDefinition不变,把合并后的属性添加给新的BeanDefinition。子BeanDefinition的属性覆盖父BeanDefinition的属性,这就是合并
合并后的BeanDefinition放在mergedBeanDefinitions里面,很重要
afterSingletonsInstantiated方法什么时候调用的?
所有的非懒加载单例Bean创建完之后,才会调用每个单例Bean的afterSingletonsInstantiated方法
isFactoryBean(beanName)方法,也很重要,很多地方有用到
@Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
}
// No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
}
return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
}
/**
* Check whether the given bean is defined as a {@link FactoryBean}.
* @param beanName the name of the bean
* @param mbd the corresponding bean definition
*/
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
Boolean result = mbd.isFactoryBean;
if (result == null) {
// 根据BeanDefinition推测Bean类型(获取BeanDefinition的beanClass属性)
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
// 判断是不是实现了FactoryBean接口
result = (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
mbd.isFactoryBean = result;
}
return result;
}