前面说到spring启动阶段会扫描bean,生成bean定义注册到容器中。容器刷新后,spring就会进入bean实例化的流程。首先合并bean定义,老版本spring基于xml文件配置bean,会大量存在父bean,此时需要进行处理,将父bean合并到当前bean定义。基于注解的bean定义,spring在扫描到后就会封装成RootBeanDefinition
注册到容器中,所以这里注解bean可以不用合并。
实现FactoryBean
接口的bean定义注册到容器时,会以FACTORY_BEAN_PREFIX(&)
为前缀,实例化bean如果发现当前的bean是FactoryBean
则默认不会调用getObject()
进行创建bean,只有在注入getObject()
生成的bean时才创建bean,除非bean实现SmartFactoryBean
接口,则通过方法isEagerInit
判断是否需要进行早期实例化,此时不管是否注入都会创建bean。
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//合并bean定义,如果bean存在父bean,则获取父bean定义到自身
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//实例化单例、非懒加载的bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//通过FactoryBean生成bean时,如果需要注入则启动时实例化,否则等到用到时候实例化
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
//如果实现了SmartFactoryBean接口,则判断是否会早期实例化
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//不管是否存在注入都通过FactoryBean生成bean
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
.......
}
getBean
为spring提供的生成bean实例对象的方法,方法很长,需要一步一步看。spring创建FactoryBean
的定义时,会在bean的name前加上FACTORY_BEAN_PREFIX(&)
,生成的bean实例会去掉FACTORY_BEAN_PREFIX(&)
,所以现在获取bean实例对象时,需要去掉"&"。然后到缓存中根据name获取实例对象,如果为FactoryBean
则判断获取的是工厂bean本身,还是生成的bean。
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//bean的名称处理,去掉"&"
String beanName = transformedBeanName(name);
Object bean;
//从缓存中获取bean,如果是FactoryBean则说明需要注入bean,此时会调用getObject方法生成bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
......
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//检查重复创建,存在重复创建说明有循环依赖的问题
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
......
//标记当前bean正在被创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//判断是否存在@DependOn导致的循环依赖问题
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) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
......//原型bean实例化
}
else {
String scopeName = mbd.getScope();
......//根据@Scope注解进行处理
}
}
}
......
return (T) bean;
}
如果获取的bean为工厂bean,则返回工厂bean本身,这里根据bean的name是否以"&"开头进行判断;没有实现FactoryBean
的工厂bean就直接返回;如果不是以"&"开头,并且又实现了FactoryBean
接口,则说明需要的是getObject
方法生成的bean,则调用getObject
方法生成bean,然后缓存下来。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
//获取的bean的name是否为工厂bean,是的话就返回工厂bean本身
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
//获取的bean为非工厂bean,而是普通bean,直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
//根据bean定义获取的FactoryBean,标记即可
if (mbd != null) {
mbd.isFactoryBean = true;
}
//先查询缓存
else {
object = getCachedObjectForFactoryBean(beanName);
}
//调用getObject方法生成bean
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
接下来是spring解决@DependsOn
导致的循环依赖问题,对bean进行实例化的时候,如果不存在循环依赖,则以被依赖的组件为key,将依赖的其他组件添加到set集合,这样就能找出依赖自身的其他组件。判断是否构成循环依赖的设计非常巧妙,首先beanName依赖dep,所以只要判断dep是否依赖beanName就行,那么可以依次获取所有直接或间接依赖beanName的组件,判断是否包含dep,如果dep也在其中,则说明dep也对beanName存在依赖关系,则构成循环依赖。
//遍历当前组件依赖的组件,进行实例化
for (String dep : dependsOn) {
//beanName依赖dep,如果dep依赖beanName的话则形成循环依赖了
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);
}
}
//保存组件的依赖关系,beanName是被依赖的组件,dependentBeanName是依赖其他组件的组件
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
//以被依赖的组件为key,将依赖组件的其他组件添加到set集合
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
//将组件作为key,其依赖的所有组件添加到set集合
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
//判断是否存在依赖关系,beanName为依赖dependentBeanName的组件,只要判断dependentBeanName是否依赖beanName即可、
//原理是找出所有直接或间接依赖beanName的组件,判断里面是否存在dependentBeanName
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
//alreadySeen表示判断过对beanName不存在依赖关系的组件
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
String canonicalName = canonicalName(beanName);
//将依赖dependentBeanName的组件beanName作为key,找出所有依赖beanName的组件
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
//如果存在dependentBeanName,则说明dependentBeanName依赖beanName,构成循环依赖
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<>();
}
alreadySeen.add(beanName);
//将当前组件的依赖组件作为key,找出依赖当前组件的依赖组件的组件,例如a依赖b,b依赖c,这里就是通过a找出间接依赖自身的c
//然后判断对自身是否存在依赖关系
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
return true;
}
}
return false;
}
通过循环依赖的检查后就到对bean进行实例化的逻辑了,首先从缓存中获取,没有获取到则开始实例化,先标记防止重复创建,然后调用传给getSingleton
的lambsingletonFactory
进行实例化。
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!)");
}
//先标记
beforeSingletonCreation(beanName);
......
try {
//生成bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
......
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//取消标记
afterSingletonCreation(beanName);
}
//缓存已经实例化的bean
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
创建bean的时候,会先尝试通过InstantiationAwareBeanPostProcessor
接口和BeanPostProcessor
生成bean,这样就不会走spring的实例化流程,算是spring提供的一种扩展机制。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
......
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
......
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
......
}
代码简化后逻辑就好看很多,分三步,先反射构造bean的实例对象,再填充bean的属性,再对bean进行实例化。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
......
instanceWrapper = createBeanInstance(beanName, mbd, args);
......
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
......
return exposedObject;
}
首先通过AutowiredAnnotationBeanPostProcessor
找出使用@Autowired
注解标注的构造器,找不到的话就使用spring解析bean阶段的获取的构造器,还没有的话就是用默认的无参构造函数,找到后就是Java反射创建bean了,填充bean的属性即依赖注入、初始化bean,等之后再讲,这也是一个繁琐的过程。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
.....
//找出使用了@Autowired注解的构造器
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
//使用解析阶段指定的构造器
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
//默认无参构造器
return instantiateBean(beanName, mbd);
}
总结下,spring对bean进行实例的时候,首先合并bean定义,然后根据name获取实例,如果是FactoryBean则按情况生成bean,之后处理@DepondOn导致的循环依赖,再找出构造器反射构造bean的实例对象。有不对的地方请大神指出,欢迎大家一起讨论交流,共同进步,更多请关注微信公众号 葡萄开源