『深入学习 Spring Boot』——Bean 实例化流程
Posted 守夜人爱吃兔子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『深入学习 Spring Boot』——Bean 实例化流程相关的知识,希望对你有一定的参考价值。
Bean 实例化
finishBeanFactoryInitialization(beanFactory)
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
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));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
这里,看起来有这么多方法,其实初始化的主体逻辑都在beanFactory.preInstantiateSingletons()
中。
preInstantiateSingletons()
这个方式是 Bean 实例化的核心方法。
简单看一下注释,就知道这个方法做了两件事:
- 初始化 Bean
- Bean 的回调处理
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) {
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) {
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());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
Bean 实例化
我们截取上面方法的实例化部分来分析:
for (String beanName : beanNames) {
// 获取 Bean 的定义。BeanDefinition 是 Spring 中对于 Bean 的描述。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象类、不是懒加载、是单例
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否工厂Bean
if (isFactoryBean(beanName)) {
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());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
// 不是工厂Bean
else {
getBean(beanName);
}
}
}
哦豁,这里面分了 工厂Bean 和 普通Bean 采取不同的处理策略。自然是先看 普通Bean 了。
getBean()
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
下面就来到了真正的逻辑doGetBean()
,但是这个方法太长了,约有150行。如果我觉得不是核心逻辑的语句,我就略去了。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 获取 beanName,有别名的用别名,工厂类的把工厂类名称前缀去掉。
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 检查缓存中是否有手动注册的单例Bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
…………
// 获取给定bean实例的对象,如果是FactoryBean,则可以是bean实例本身或其创建的对象。
bean = 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);
}
........
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 先加载当前Bean 定义了DpendsOn的类
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// 遍历处理 DpendsOn 类
for (String dep : dependsOn) {
....
// 为当前实例化中的bean注册一个从属bean
registerDependentBean(dep, beanName);
try {
// 递归调用,获取Dpends 实例化的Bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建 Bean
return createBean(beanName, mbd, args);
}
...........
});
.........
}
............
return (T) bean;
}
我们继续进入到createBean(beanName,mbd,args)
中:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
........
RootBeanDefinition mbdToUse = mbd;
........
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
........
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
......
return beanInstance;
}
........
}
主要到这里有两个比较重要的方法:resolveBeforeInstantiation(beanName, mbdToUse)
、 doCreateBean(beanName, mbdToUse, args)
。
resolveBeforeInstantiation
// 执行 Bean 实例化的,前后处理器。
// 从文档注释来看,这里可以指定Bean实例化的快捷方式
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 实例化 Bean 前置处理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 实例化 Bean 后置处理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
// 实现了 InstantiationAwareBeanPostProcessor 的Bean,执行 postProcessBeforeInstantiation
// 这个应该是上面所指的实例化快捷方式,我们可以实现 InstantiationAwareBeanPostProcessor 后,在postProcessBeforeInstantiation方法中,自定义实例化Bean 的逻辑。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
很显然,我们一般不会这么搞的。我们日常时候都是直接注解一下就ok,并不会自定义Bean的实例化逻辑。
doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
......
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
......
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
......
......
.....
return exposedObject;
}
这里面呢,有三个主要方法需要我们注意:createBeanInstance(beanName, mbd, args)
、populateBean(beanName, mbd, instanceWrapper)
、initializeBean(beanName, exposedObject, mbd)
。
-
createBeanInstance
使用适当的实例化策略为指定的bean创建一个新实例。
-
populateBean
使用Bean定义中的属性值填充给定BeanWrapper中的Bean实例。
-
initializeBean
初始化给定的bean实例,应用工厂回调以及init方法和bean post处理器。 对于传统定义的bean,从createBean调用,对于现有的bean实例,从initializeBean调用。
createBeanInstance
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); ... // 使用命名工厂方法实例化bean。 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; ...... if (resolved) { if (autowireNecessary) { // 构造函数注入 return autowireConstructor(beanName, mbd, null, null); } else { // 使用其默认构造函数实例化给定的bean。 return instantiateBean(beanName, mbd); } } ...... // 使用无参构造,实例化Bean return instantiateBean(beanName, mbd); }
populateBean
不是重点。
initializeBean
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { ..... else { // 判断实现了哪一种 Aware 接口,调用对应的方法 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 巨熟悉的方法:实例化的前置处理 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 调用Bean的 afterPropertiesSet() 方法 invokeInitMethods(beanName, wrappedBean, mbd); } ...... if (mbd == null || !mbd.isSynthetic()) { // 实例化的后置处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } // 返回 Bean return wrappedBean; }
总结
Bean 的实例化总体流程,我们就此走完了。
Bean 的实例化过程,还是非常复杂的。所以我们这节,还是重在总体流程的理解,细枝末节的以后再探究。
在探究 Bean 的实例过程中,我们看到了,很多判断是否实现了某接口,然后调用接口方法的逻辑,例如 BeanPostProcessors。这是 Spring 里非常常用的手法。
最后
最近我整理了整套《JAVA核心知识点总结》,说实话 ,作为一名Java程序员,不论你需不需要面试都应该好好看下这份资料。拿到手总是不亏的~我的不少粉丝也因此拿到腾讯字节快手等公司的Offer
进【Java进阶之路群】,找管理员获取哦-!
以上是关于『深入学习 Spring Boot』——Bean 实例化流程的主要内容,如果未能解决你的问题,请参考以下文章
Java框架spring Boot学习笔记:Bean的作用域
Spring Boot 学习系列(09)—自定义Bean的顺序加载
Spring Boot 学习系列(09)—自定义Bean的顺序加载