在对于不是实现代理类是通过调用 doCreateBean 方法来创建对象的:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
// 首先实例化一个bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 从三级缓存删除,factoryBeanInstanceCache存的是beanName对应的FactoryBean实例对象
// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来(比如依赖注入过程中)
// 单例情况下清除缓存。这里保存的是 FactoryBean 和 BeanWrapper 的映射关系。
// factoryBeanInstanceCache是在创建其他bean的时候缓存了一下FactoryBean 。
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果没有缓存,则重新创建
if (instanceWrapper == null) {
// 1. 创建Bean实例:根据指定的bean使用对应的策略创建新的实例。如:工厂方法、构造函数自动注入,简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
// 见2.7.1.2 allpyMergedBeanDefinitionPostProcessors
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;
}
}
// 用于解决循环依赖,详见2.7.1.3
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
// 用于初始化bean,详见2.8.1
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
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);
}
}
// 2.8.3 二级缓存检查
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// 2.9 bean的销毁
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 确认需要创建的bean实例的类可以实例化
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 确保class不为空,并且访问权限是public
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());
}
// 判断当前beanDefinition中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方法不为空则使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
// Shortcut when re-creating the same bean...
// 标记下,防止重复创建同一个bean
boolean resolved = false;
// 是否需要自动装配
boolean autowireNecessary = false;
// 如果没有参数
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 因为一个类可能由多个构造函数,所以需要根据配置文件中配置的参数或传入的参数来确定最终调用的构造函数。
// 因为判断过程会比较,所以spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
// 在下次创建相同时直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 有构造参数的或者工厂方法
if (resolved) {
// 构造器有参数
if (autowireNecessary) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有@Autowired注解构造
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 以下情况符合其一即可进入
// 1、存在可选构造方法
// 2、自动装配模型为构造函数自动装配
// 3、给BeanDefinition中设置了构造参数值
// 4、有参与构造函数参数列表的参数
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.
// 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
return instantiateBean(beanName, mbd);
}
createBeanInstance() 方法是 spring 实例化 bean 的核心代码,它根据不同的情况会调用四种实例化方法
Supplier 是 Java8 的一个函数式接口。该接口中就一个 get() 方法。
从上述代码可以看到 Spring 是从 mbd中得到的 Supplier 。既然可以得到那就可以进行设置。instanceSupplier属性是属于 AbstractBeanDefinition 抽象类的。
public void setInstanceSupplier(@Nullable Supplier<?> instanceSupplier) {
this.instanceSupplier = instanceSupplier;
}
public <T> RootBeanDefinition(@Nullable Class<T> beanClass, @Nullable Supplier<T> instanceSupplier) {
super();
setBeanClass(beanClass);
setInstanceSupplier(instanceSupplier);
}
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
ctx.registerBean(Person.class, new Supplier<Person>() {
@Override
public Person get() {
return new Person("gongj");
}
});
如果 RootBeanDefinition 类中存在 factoryMethodName 属性,或者在配置文件中配置了 factory-method 或 factory-bean 标签,spring 会尝试使用 instantiateUsingFactoryMethod() 方法进行 bean 的实例化
public class UserFactory {
// 静态方法
public static User getUser1() {
return new User();
}
}
xml配置文件
<!-- 使用静态工厂实例化 user -->
<bean id="user1" class="ioc.service.UserFactory" factory-method="getUser1"></bean>
public class UserFactory {
// 普通方法
public User getUser2() {
return new User();
}
}
xml配置文件
<!-- 使用实例工厂实例化 user -->
<bean id="userFactory" class="ioc.service.UserFactory"></bean>
<bean id="user2" factory-bean="userFactory" factory-method="getUser2"></bean>
@Bean
public ShiroDialect getShiroDialect() {
return new ShiroDialect();
}
简单来说,就是根据传入的参数列表,来匹配合适的有参构造器进行 bean 的实例化
不赘述了。
这里的逻辑一句话概括 : 是否有方法被覆盖(是否使用 replace 或 lookup 进行配置),有则使用 cglib 动态代理,增强方法,否则直接通过反射实例化 bean。这一块判断方法是否被重写,不是为了事务或者 aop,因为解析还没到那一步,这里是为了 lookup-method 和 replaced-method 标签
该方法处于 spring 创建 bean 的入口阶段,会使用各种方法来尝试完成 bean 的实例化。对于具体使用那种方式进行实例化,spring 会使用类 RootBeanDefinition 去解析 xml 和注解类型的配置文件
但是并未完成属性填充、接口特性实现(如 Aware)、标签设置(如 inti-method)的设置。在后续的 AbstractAutowireCapableBeanFactory#populateBean() 方法中完成了属性的填充
Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工,
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(mbd, beanType, beanName)根据名称可以知道这是一个操作BeanDefinition的增强器,可以去修改BeanDefinition中的属性,但是注意这个的执行时机,是在 bean 实例化之后在执行的,所以说现在修改 BeanDefiniton的有些属性是无效的,比如beanClss属性,因为bean已经创建了。
此处的 PostProcessor的类型为:MergedBeanDefinitionPostProcessor。
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
此处的逻辑很简单,就是执行该类型的后置处理器的后置处理方法。
我们点进去MergedBenDefinitionPostProcess类

从源码中可以看到,接口MergedBeanDefinitionPostProcessor中定义了两个方法:
postProcessMergedBeanDefinition()方法是Spring用于找出正在创建的bean中所有需要注入的字段并同时做缓存的,resetBeanDefinition()方法是在BeanDefinition被修改后清除容器的缓存的。
我们点击向下 图标查看下postProcessMergedBeanDefinition()方法的实现类,可以发现这些实现类中几乎都包含"AnnotationBeanPostProcessor",所以他们其实都是注解相关的BPP,各自有负责处理的注解
(比如CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor)

// 此处用于解决循环依赖问题
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
循环依赖的问题背景:
https://zhuanlan.zhihu.com/p/462247516
https://blog.csdn.net/ywl470812087/article/details/127725977
earlySingletonExposure表示是否提前暴露,是的话就执行addSingletonFactory方法,将该bean暴露到第三级缓存,这样就可以解决特定场景的循环依赖问题。而getEarlyBeanReference就是返回这个bean的一个直接引用。为什么是个引用啊?很明显,现在的bean还是不完整的,别的bean,起个名字叫B,如果依赖咱们的A,那么就会从三级缓存中拿到A的直接引用,但是咱们说了A是不完整的,所以拿个引用,后续A完整了,那么B中依赖的bean不就完整了吗。。
下面就是初始化bean的过程了。populateBean的主要作用就是填充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 {
// 下面的注释讲解的很到位,给到任何一个InstantiationAwareBeanPostProcessors一个机会去修改bean的属性。
// 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.
/*
这一段代码是Spring用来提供给程序员扩展使用的, 如果我们不希望一个bean参与到属性注入, 自动装配的流
程中, 那么就可以创建一个InstantiationAwareBeanPostProcessor后置处理器的实现类, 重写其
postProcessAfterInstantiation方法, 如果该方法返回false, 那么continueWithPropertyPopulation
这个变量会被置为false, 而这个变量被置为false, 在下面我们可以看到直接就return了, 从而Spring就不
会对属性进行注入
*/
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var4 = this.getBeanPostProcessors().iterator();
while(var4.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var4.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
/*
这一段代码是当我们手动设置了注入模型为byType/byName的时候, Spring就会利用Java的内省机制拿到所有的
set方法, 如果一个set方法有参数, Spring就会将其封装成一个PropertyValue, 然后放入到新创建的newPvs
中, 最终用这个newPvs来替换原来的pvs, 这里有一个注意点, 在获取pvs的时候, 如果程序员没有提供, pvs
被设置成了null, 因为 mbd.getPropertyValues()这段代码始终是能拿到一个集合对象的, 只是这个集合对象
中没有PropertyValue而已
*/
// 下面是两种注入方法,分别是byName和byType。
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
//在populateBean方法中,有两种注入方法,分别为byName和byType。将所有符合的bean统一存到了PropertyValues中。
if (resolvedAutowireMode == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
/* 分析: 在这段代码中, 如果pvs == null, Spring就获取beanDefinition中的集合对象了, 如果pvs == null,
我们也可以推断出, 程序员没有提供PropertyValue, 同时, 该beanDefinition也不是byName/byType的, 之后
Spring会调用InstantiationAwareBeanPostProcessor.postProcessProperties方法, 在之前我们分析
applyMergedBeanDefinitionPostProcessor的时候, 有讲解到, Spring会将所有需要被注入的属性/方法封装
成一个InjectedElement, 然后放入到InjectionMetadata中, 而这个InjectionMetada是位于后置处理器中的,
这是一个策略模式的应用, 不同的后置处理器处理不同的注入类型, 而在当前这一步, 就是遍历这些不同的后置
处理器, 开始将它们中的InjectionMetadata拿出来, 取出一个个InjectedElement完成注入
*/
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
/*
如果pvs不为null, Spring就会开始遍历里面的一个个PropertyValue, 通过反射调用setXXX方法来完成注入,
所以这就很好理解为什么当注入模型为byName/byType的时候, Spring能完成自动注入了*/
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
InstantiationAwareBeanPostProcessor的后置处理器postProcessAfterInstantiation,实现这个接口的在这里都会调用后置处理器。

可以看出,如果后置方法返回false那就直接return了,不会走后面的postProcessProperties方法了。

进行属性填充,Autowired注解就是通过上面第二个来进行属性注入的。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
// 2.8.2.1
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = this.getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
}
}
如果Bean实现BeanNameAware接口,调用setBeanName设置名字
如果Bean实现BeanFactoryAware接口,调用setBeanFactoryAware设置BeanFactory
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
实现BeanPostProcessor接口,定义该前置方法就可以做初始化前的操作。
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 首先先检查是否是InitializingBean,如果是,则需要调用afterPropertiesSet()
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
// 安全模式
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
// 属性初始化处理
((InitializingBean) bean).afterPropertiesSet();
}
}
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);
}
}
}
分析:
从invokeInitMethods方法中,我们知道init-method指定的方法会在afterPropertiesSet方法后执行,如果afterPropertiesSet方法执行过程中出现异常,init-method方法是不会执行的。使用init-method使其对业务代码的侵入降低,虽然init-method是基于xml配置文件的,但我们也可以通过@PostConstruct注解的形式来进行替换。
invokeCustomInitMethod是执行用户可以自定义初始化方法,比如用xml的init-method或者@Bean指定的方法。同时跟afterPropertiesSet不冲突。可以看到,上面源码,先执行afterPropertiesSet方法,然后执行invokeCustomInitMethod。
其实@PostConstruct就是在一个BeanPostProcessor的实现类的postProcessBeforeInitialization方法中被调用的,这个类就是InitDestroyAnnotationBeanPostProcessor类。


在spring的bean的生命周期中,实例化->生成对象->属性填充后会进行afterPropertiesSet方法,这个方法可以用在一些特殊情况中,也就是某个对象的某个属性需要经过外界得到,比如说查询数据库等方式,这时候可以用到spring的该特性,只需要实现InitializingBean即可:
@Component("a")
public class A implements InitializingBean {
private B b;
public A(B b) {
this.b = b;
}
@Override
public void afterPropertiesSet() throws Exception {
}
}
这样可以在afterPropertiesSet方法中进行你的额外操作。
实现BeanPostProcessor接口,定义该后置方法就可以做初始化后的操作。
bean初始化完成之后,后面还有一步去检查:第二级缓存是否存在, 代理对象和原始对象是否相等。
下面是继续执行docreatebean的代码
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(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 " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
// 当前 bean 的作用域不是 Prototype && requiresDestruction 返回 true
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// bean 的作用域是单例的
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
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, getBeanPostProcessors(), acc));
}
}
}
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean.getClass() != NullBean.class &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
}
可以看到 requiresDestruction() 方法只要满足下面任意一个即可

总结一下,requiresDestruction方法就是看一下有没有实现销毁方法,包括注解实现、Beadefinition中指定、当前bean的close方法和shutdown方法。如果确定有销毁方法,那就进行下一步,

<bean id="person" class="com.meimeixia.bean.Person" init-method="init" destroy-method="destroy">
<property name="age" value="18"></property>
<property name="name" value="liayun"></property>
</bean>
package com.meimeixia.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.meimeixia.bean.Car;
@Configuration
public class MainConfigOfLifeCycle {
@Bean(initMethod="init", destroyMethod="destroy")
public Car car() {
return new Car();
}
}
package com.xk.spring.init;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 用于如何配置讲解bean的初始化方法
* @author xk
* @since 2023.04.30 15:26
*/
public class RedisService implements InitializingBean, DisposableBean {
public RedisService(){
System.out.println("这是RedisService构造方法");
}
public void initMethod(){
System.out.println("(1)这是一个@Bean initMethod初始化方法");
}
@PostConstruct
private void initMethod2(){
System.out.println("(2)这是一个@PostConstruct初始化方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("(3)这是一个InitializingBean初始化方法");
}
public void destroyMethod(){
System.out.println("(1)这是一个@Bean destroyMethod销毁方法");
}
@PreDestroy
public void destroyMethod2() {
System.out.println("(2)这是一个@PreDestroy销毁方法");
}
}
package com.xk.spring.init;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 用于如何配置讲解bean的初始化方法
* @author xk
* @since 2023.04.30 15:26
*/
public class RedisService implements InitializingBean, DisposableBean {
public RedisService(){
System.out.println("这是RedisService构造方法");
}
public void initMethod(){
System.out.println("(1)这是一个@Bean initMethod初始化方法");
}
@PostConstruct
private void initMethod2(){
System.out.println("(2)这是一个@PostConstruct初始化方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("(3)这是一个InitializingBean初始化方法");
}
public void destroyMethod(){
System.out.println("(1)这是一个@Bean destroyMethod销毁方法");
}
@PreDestroy
public void destroyMethod2() {
System.out.println("(2)这是一个@PreDestroy销毁方法");
}
@Override
public void destroy() throws Exception {
System.out.println("(3)这是一个DisposableBean销毁方法");
}
}
package com.xk.spring.init;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* 用于如何配置讲解bean的初始化方法
* @author xk
* @since 2023.04.30 15:26
*/
public class RedisService implements InitializingBean, DisposableBean {
public RedisService(){
System.out.println("这是RedisService构造方法");
}
public void initMethod(){
System.out.println("(1)这是一个@Bean initMethod初始化方法");
}
@PostConstruct
private void initMethod2(){
System.out.println("(2)这是一个@PostConstruct初始化方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("(3)这是一个InitializingBean初始化方法");
}
public void destroyMethod(){
System.out.println("(1)这是一个@Bean destroyMethod销毁方法");
}
@PreDestroy
public void destroyMethod2() {
System.out.println("(2)这是一个@PreDestroy销毁方法");
}
@Override
public void destroy() throws Exception {
System.out.println("(3)这是一个DisposableBean销毁方法");
}
}
这是RedisService构造方法
(2)这是一个@PostConstruct初始化方法
(3)这是一个InitializingBean初始化方法
(1)这是一个@Bean initMethod初始化方法
(2)这是一个@PreDestroy销毁方法
(3)这是一个DisposableBean销毁方法
(1)这是一个@Bean destroyMethod销毁方法
@PreDestroy指定的方法–>DisposableBean接口的destroy方法–>@Bean的destroyMethod属性指定的方法(或者是xml定义的)
同理,其实@PreDestroy也是在一个BeanPostProcessor的实现类的postProcessBeforeInitialization方法中被调用的,这个类依然是InitDestroyAnnotationBeanPostProcessor类。这个类是DestructionAwareBeanPostProcessor的实现类,所以可以制定销毁的前置方法postProcessBeforeDestruction,而@PreDestroy就在这里通过反射起作用。


就如同注释说的
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
而 DisposableBeanAdapter:org.springframework.beans.factory.support.DisposableBeanAdapter#destroy方法
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
Iterator var1 = this.beanPostProcessors.iterator();
while(var1.hasNext()) {
DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor)var1.next();
// 至关重要的!
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
((DisposableBean)this.bean).destroy();
return null;
}, this.acc);
} else {
((DisposableBean)this.bean).destroy();
}
} catch (Throwable var3) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, var3);
} else {
logger.warn(msg + ": " + var3);
}
}
}
if (this.destroyMethod != null) {
this.invokeCustomDestroyMethod(this.destroyMethod);
} else if (this.destroyMethodName != null) {
Method methodToInvoke = this.determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
this.invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
这里postProcessBeforeDestruction是一个beanPostProcessor类的拓展点,会调用bean销毁的前置方法。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
void postProcessBeforeDestruction(Object var1, String var2) throws BeansException;
default boolean requiresDestruction(Object bean) {
return true;
}
}
可以自己实现postProcessBeforeDestruction方法,作为销毁类前的拓展点。