前面我们主要学习了Spring启动过程中的的扫描逻辑和一些前置的铺垫知识,扫描主要是获取到BeanDefinition。获取后其实就是要基于BeanDefinition去创建Bean对象了。上篇文章中我们分析FactoryBean时,其实已经开始分析getBean方法了。那么从这一篇文章开始将进入getBean方法核心源码的分析。这个getBean方法,我们学习入门demo的时候就调用过,另外依赖注入的过程中也会调用getBean方法。而getBean方法内部就有调用createBean方法创建Bean的逻辑。
课程内容:
@DependsOn注解工作的底层源码解析
Bean的作用域实现底层源码解析
Spring类加载过程底层源码解析
Bean生命周期之实例化前底层源码解析
Bean生命周期之实例化底层源码解析
Bean生命周期之BeanDefinition后置处理底层源码解析
Bean生命周期之实例化后底层源码解析
Bean生命周期之Spring自动注入底层源码解析
Bean生命周期之属性处理底层源码解析
Bean生命周期之Aware回调底层源码解析
Bean生命周期之初始化前底层源码解析
Bean生命周期之初始化底层源码解析
Bean生命周期之初始化后底层源码解析
Bean创建过程生命周期流程图

由此可见,Bean的生命周期之间的步骤还是非常多的,我们会分多篇文章完成学习。本文对于一些步骤不会深入分析其实源码实现,主要关注于扩展点和整个生命周期的一个大致流程。
doGetBean方法导读
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
UserService userService = applicationContext.getBean("userService", UserService.class);
System.out.println(userService);
}
}这里我们手动调用getBean方法,大概的流程就是先根据名称获取,再转换类型。通过断点可以进入:
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法,此方法就是上篇文章中分析FactoryBean也进入的方法,下面开始逐行分析。
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)此方法就是去单例池获取,里面有解决循环依赖的三级缓存,这个后面学习,目前只要知道:不管是单例还是多例Bean,都会从单例池中获取一次,这里Spring没有去判断作用域了。
如果单例池中获取不到就走else逻辑,一般第一次获取都会走else分支,if分支我们上篇文章分析FactoryBean已经分析过,下面重点分析else分支代码。这里我们先跳过中间代码,直接看最后:
// 判断创建的Bean对象的类型是否是需要的类型,如果不是则进行类型转换
return adaptBeanInstance(name, beanInstance, requiredType);
org.springframework.beans.factory.support.AbstractBeanFactory#adaptBeanInstance 此方法很容易理解,它还调用了我们之前学习的Convert机制。
中间还有很多代码下面我们一一分析。进入else分支可能是单例Bean第一次进入,可能是多例Bean,也可能是其他作用域(含自定义作用域)的Bean。
上来就有个判断,这个先跳过,大概就是多例Bean循环依赖就报错,因为无法解决。
再下面就是一个类似于双亲委派的机制,因为BeanFactory可以存在父子关系,如下代码:
DefaultListableBeanFactory beanFactory1 = new DefaultListableBeanFactory();
DefaultListableBeanFactory beanFactory2 = new DefaultListableBeanFactory();
beanFactory1.setParentBeanFactory(beanFactory2);
这个我们自己用的少,但是SpringMVC中有用到,后面学习。// 接下来是一个标记操作
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
// 再后面就是一个JFR机制,打了个tag,这个之前学习过
// 再后面是一个合并BeanDefinition的操作,然后有一个是否抽象BeanDefinition的检查再往后面就是核心代码了,看起来步骤比较多,但是并不是很难,下面我们一段段分析,先是一个DependsOn的处理。这个目前我用的较少,开发中几乎没有用过,先来了解下@DependsOn注解。
@DependsOn注解
@DependsOn的作用:用于显式声明Bean的创建依赖关系,确保依赖的Bean先被创建
@DependsOn的触发时机
来看一段代码:
@Component
@DependsOn("orderService") // 值是数组类型
public class UserService {
@Autowired
private OrderService orderService;
public void test() {
System.out.println("UserService#test....");
}
}@DependsOn("orderService")是一种依赖关系,当然直接字段注入orderService也是一种依赖关系,但是Spring中对于两者处理逻辑截然不同。在创建UserService这个Bean的时候,如果有@DependsOn依赖项,必须先保证依赖的Bean被创建,才会继续创建UserService这个Bean,而字段的OrderService是在后面的依赖注入过程处理的,也就是说两者的触发时机如下:
@DependsOn是在Bean创建开始前检查的
而@Autowired是在Bean创建后,属性填充阶段处理的
影响Bean创建的顺序
这个也在一定程度上,确定了Bean创建的顺序,如下代码:
@Component
public class MemberService {
@Autowired
private UserService userService;
}如果先扫描到MemberService那么会getBean("userService"),而UserService又依赖了OrderService,所以最终的顺序是:
OrderService --> UserService --> MemberService
循环依赖问题
有一个特别要注意的问题,那就是循环依赖的场景,如下代码:
@Component
@DependsOn("userService")
public class OrderService {
}@Component
@DependsOn("orderService")
public class UserService {
public void test() {
System.out.println("UserService#test....");
}
}这种循环依赖是解决不了的,加@Lazy也没有效果的,Spring会直接报错。但@Autowired这种循环依赖是可以通过三级循环解决。
源码处理分析
这个源码就是接着之前的doGetBean方法里面的。
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
// 判断beanName是不是被dep依赖了,dependsOn出现了循环依赖(这个就是两个bean相互@DependsOn对方,这种是无法解决的,即使@Lazy也没有用)
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// 注册依赖
// dep被beanName依赖了
// beanName依赖了dep
// 就是保存到两个map中,上面的isDependent方法就要用到这里的map去判断
registerDependentBean(dep, beanName);
try {
// 创建依赖的Bean,和当前Bean的创建是在同一个线程
// 如果多例也是会调用下,这里只是保证依赖项一定能创建的出来,也就是调用getBean不报错
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
catch (BeanCreationException ex) {
if (requiredType != null) {
// Wrap exception with current bean metadata but only if specifically
// requested (indicated by required type), not for depends-on cascades.
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Failed to initialize dependency '" + ex.getBeanName() + "' of " +
requiredType.getSimpleName() + " bean '" + beanName + "': " +
ex.getMessage(), ex);
}
throw ex;
}
}
}总结
/**
* @DependsOn 注解详解
*
* 作用:显式声明Bean的创建顺序依赖
*
* 与@Autowired的区别:
* 1. @DependsOn - 控制Bean的**实例化顺序**(创建时机)
* 2. @Autowired - 控制Bean的**依赖注入**(属性赋值)
*
* 执行时机:
* 1. BeanDefinition加载阶段:记录@DependsOn信息
* 2. Bean创建阶段:检查依赖,确保依赖Bean先创建
* 3. 依赖注入阶段:进行@Autowired注入
*
* 示例流程:
* 扫描顺序:MemberService → UserService → OrderService
* 创建顺序:OrderService → UserService → MemberService
*
* 注意:
* - 可以依赖多个Bean:@DependsOn({"bean1", "bean2"})
* - 避免循环依赖(与@Autowired不同,没有三级缓存解决机制)
* - 主要用于非显式引用但需要先初始化的Bean(如数据库连接池等)
*/Bean的作用域实现
前面介绍了@DependsOn,相当于选择会去调用getBean获取依赖项。接着就是真的创建自己的Bean了,这里就会涉及到多种作用域。下面的代码,分成了三种情况,一种是单例,一种是多例,除此之外统称为其他作用域。
// 开始创建当前Bean
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return 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.
destroySingleton(beanName);
throw ex;
}
});
// 如果是FactoryBean则返回getObject()对应的Bean对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
// 创建Bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// request、session
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
if (!isCacheBeanMetadata()) {
clearMergedBeanDefinition(beanName);
}
}
}上面的三者的代码是类似的,都会调用createBean方法,并且都会去调用getObjectForBeanInstance(也就是处理FactoryBean的情况)。这里可以补充一下FactoryBean是多例的情况,观察如下代码的执行结果:
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyFactoryBean implements FactoryBean<User> { // &myFactoryBean:MyFactoryBean对象 myFactoryBean:User对象
@Override
public User getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println(applicationContext.getBean("myFactoryBean"));
System.out.println(applicationContext.getBean("myFactoryBean"));
System.out.println(applicationContext.getBean("myFactoryBean"));
}
}
/*
com.hexon.User@4d5d943d
com.hexon.User@368f2016
com.hexon.User@4c583ecf
*/这个看源码就知道是什么回事,也就是MyFactoryBean是多例,会多次调用getObject
因为三者的代码类似,下面我们先来分析单例Bean的创建,但要注意的是代码走到了这里就会去创建,因为前面已经检查过单例池中是没有的。
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)方法里面传入了一个lambda表达式,也就是一个对象。
此方法在我这个版本中被重写了,增加了一些并发的判断,但是核心就是创建Bean,并放入了单例池。而对于原型Bean,就没有那么复杂了,它上来就是createBean。下面重点看下其他作用域Bean的创建:
这个地方主要看org.springframework.beans.factory.config.Scope接口的具体实现类,比如:org.springframework.web.context.request.RequestScope
再看传入lambda的org.springframework.beans.factory.config.Scope#get方法
最终调用到org.springframework.web.context.request.AbstractRequestAttributesScope#get
org.springframework.web.context.request.RequestContextHolder#currentRequestAttributes 这个相当于是在拿Request
// 获取当前线程绑定的RequestAttributes对象,在Web应用中,通常就是ServletRequestAttributes,它包装了HttpServletRequest和HttpServletResponse
// Spring MVC会设置RequestContextHolder
org.springframework.web.context.request.RequestAttributes#getAttribute
// 具体实现
org.springframework.web.context.request.ServletRequestAttributes#getAttribute,此方法就会getAttribute所以,其实所谓的作用域,就是把创建的Bean放入到不同对象的map中。
源码看到这里基本doCreateBean方法的外层我们已经分析完了,当然里面还有一些循环依赖的处理,这些后面学习的时候要能回忆起。
下面我们对不同作用域的Bean的创建核心流程做一个简单的小结:
单例Bean:先去单例池查看有没有,没有就创建,再放入单例池
多列Bean:先去单例池查看有没有,没有就直接创建
其他作用域Bean:先看自己作用域(map)里面有没有,没有就创建,再放入自己的作用域中
Spring类加载过程分析
前面已经分析了doCreateBean方法的外层,里核心的方法是:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
这个其实就是通往更核心逻辑的一个新入口。
首先我们观察到这个方法,有一个args参数,我们在getBean的时候其实就可以传递args参数,这个其实与推断构造方法有关。思考如下代码:
@Component
public class UserService {
private String name;
public UserService(String name) {
this.name = name;
System.out.println("1");
}
public UserService() {
System.out.println("0");
}
public void test() {
System.out.println("UserService#test....");
}
}public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
// 推断构造方法
applicationContext.getBean("userService", "danny");
}
}
// 打印的也是0,这是因为Spring容器启动的时候就创建了UserService,可以在无参构造中打个断点,看下调用链路我们只要把UserService改成原型或者懒加载就可以打印出1(前提是没有其他类注入UserService干扰)
@Component
// @Lazy
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserService {
private String name;
public UserService(String name) {
this.name = name;
System.out.println("1");
}
public UserService() {
System.out.println("0");
}
public void test() {
System.out.println("UserService#test....");
}
}其实这个代码用原型作用域测试更好,因为前面我们有个MemberService里面注入了UserService,你直接只用@Lazy,结果还是打印0,你可能会懵逼。
OK,现在我们只是明白了createBean方法的3个参数的含义,具体的推断构造方法后面会单独用一篇文章来分析,我们先来分析类加载的过程。为了加深这一块的理解先将代码改回最简单的形式,进行调试:
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
applicationContext.getBean("userService");
}
}@Component
public class UserService {
public void test() {
System.out.println("UserService#test....");
}
}断点方法:org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass

主要调试org.springframework.beans.factory.support.AbstractBeanFactory#doResolveBeanClass方法。
此方法里会去加载类,这里有个细节,那就是BeanDefinition的beanClass属性是一个Object,开始时是字符串对象,加载类后就是Class对象。
这个代码调用比较深,但最终就是调用org.springframework.util.ClassUtils#forName方法,
最终通过jdk的Class.forName加载类。
这里有一个细节要注意,就是Spring默认加载类时用的类加载器是什么。
要创建一个Bean对象,就必须得先保证类被加载了,而类加载就涉及到用哪个类加载器。
通过代码调试,可以知道org.springframework.util.ClassUtils#getDefaultClassLoader此方法中体现了Spring选择ClassLoader的逻辑:
1. 优先返回当前线程中的ClassLoader
2. 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
3. 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器
调试org.springframework.util.ClassUtils#getDefaultClassLoader方法可以发现,默认的值是Thread.currentThread().getContextClassLoader();这个直接看java.lang.Thread#getContextClassLoader方法的注释,上面写的很清楚:JVM启动时创建的第一个线程(main线程)的上下文类加载器通常是 AppClassLoader。
而我们这刚好是主线程运行的。当然Spring作为一个通用的框架,它也提供的设置类加载器的方法:
public class Main {
public static void main(String[] args) {
// 获取应用启动的时候就设置线程的(这个SpringBoot应用或者说就是Tomcat容器中会有自己类加载器,它要让各个应用的类加载是隔离的)
Thread.currentThread().setContextClassLoader(Main.class.getClassLoader());
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
// 指定classLoader
// applicationContext.getBeanFactory().setBeanClassLoader(Main.class.getClassLoader());
applicationContext.getBean("userService");
}
}上面展示了两种方式:一种是直接给线程设置,一种是setBeanClassLoader
类加载完成后,就要真正进行创建了,也是进入真正的生命周期的过程了。
实例化前
当前BeanDefinition对应的类成功加载后,就可以实例化对象了,但是在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个Bean实例化之前做一些其他动作。这个扩展点叫InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()。
这里就要提及到BeanPostProcessor了,我们先看org.springframework.beans.factory.config.BeanPostProcessor接口,这个接口只提供了初始化前和初始化后。看下面代码:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName);
System.out.println("初始化前");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化后");
return bean;
}
}这个其实就相当于一个"插件",它会作用于所有的Bean,这个我们在前面手写Spring核心原理中已经讲解过了。Spring中也内置了很多,你比如说:
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor -- 处理@Autowired注解
而源码中org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation方法内部其实就是有缓存所有的BeanPostProcessor,其中这里实例化前就是用的org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口。
这个地方应该是历史原因,最初可能压根没有考虑实例化前后还扩展,所以后面InstantiationAwareBeanPostProcessor继承BeanPostProcessor接口,扩展了三个方法,分别是postProcessBeforeInstantiation(实例化前)、postProcessAfterInstantiation(实例化后)、postProcessProperties(属性设置)。
我们改造下MyBeanPostProcessor的代码:
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化前");
}
// 看源码就知道:这个地方可以返回任意类型,没有说一定要是beanClass的类型
// 当然一般是生成代理类返回
// 源码位置:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation
return new User();
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化后");
}
return true;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}@Component
public class UserService {
public void test() {
System.out.println("UserService#test....");
}
}public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
System.out.println(applicationContext.getBean("userService"));
}
}这个地方可能会有一个报错:
实例化前
初始化后
12月 25, 2025 8:34:09 下午 org.springframework.context.support.AbstractApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myFactoryBean': Bean instance of type [class com.hexon.User] is not a FactoryBean
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myFactoryBean': Bean instance of type [class com.hexon.User] is not a FactoryBean
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getFactoryBean(FactoryBeanRegistrySupport.java:246)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getNonSingletonFactoryBeanForTypeCheck(AbstractAutowireCapableBeanFactory.java:1116)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:923)
at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:690)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:652)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:620)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:606)
at org.springframework.context.event.EventListenerMethodProcessor.afterSingletonsInstantiated(EventListenerMethodProcessor.java:115)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1153)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:999)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:637)
at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:97)
at com.hexon.Main.main(Main.java:14)Spring 在启动时检查所有 bean(包括你没 get 的 bean)是为了确保容器完整性,防止后续运行时出现不可预知的错误。
这个是之前的代码有干扰。
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyFactoryBean implements FactoryBean<User> { // &myFactoryBean:MyFactoryBean对象 myFactoryBean:User对象
@Override
public User getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}去掉@Component代码就会正常输出:
实例化前
初始化后
com.hexon.User@60d8c9b7或者调整下MyBeanPostProcessor的代码
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化前");
return new User();
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化后");
}
return true;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}值得注意的是,postProcessBeforeInstantiation()是有返回值的,如果这么实现:
userService这个Bean,在实例化前会直接返回一个由我们所定义的User对象。如果是这样,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。
中间的步骤是跳过了,但是初始化后会进行AOP,不会跳过
如果实例化前没有操作或者返回的是null,再后面就是真正的交由Spring去创建了。
实例化
入口方法:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
Spring当然也是首先要去实例化创建对象,在这个步骤中就会根据BeanDefinition去创建一个对象。对应的具体方法是:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
此方法中会进行:推断构造方法、构造方法注入、@Bean的处理
此方法会在后面单独分析,目前只要知道这个方法会返回一个包装了的对象,其中包含创建完成的实例。
BeanDefinition的后置处理
Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工。
方法入口:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors方法
这里也是一个BeanPostProcessor,具体的类型是:org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor
此接口中有两个方法,其中resetBeanDefinition是默认方法我们暂时不关注,我们实现下它:
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化前");
// return new User();
}
return null;
}
// 处理合并以后的BeanDefinition,此方法在源码中对于在实例化后初始化之前被调用
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 这个地方可以修改BeanDefinition的值,影响后续的步骤,前面的步骤是不受影响的,你比如你改beanClass是没有用的,对象都创建了
if ("userService".equals(beanName)) {
System.out.println("BeanDefinition的后置处理");
// ✅ 有效的修改(影响后续步骤):
// 1. 修改属性值 - 会影响 @Autowired/@Value 注入
beanDefinition.getPropertyValues().add("name", "danny");
// 2. 修改初始化/销毁方法
beanDefinition.setInitMethodName("a");
// 3. 修改是否自动装配
// beanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
// 4. 修改 Bean 的作用域
// beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
// ❌ 无效的修改(不会影响已发生的步骤):
// 1. 修改 beanClass - 实例已创建,不会再重新创建
// beanDefinition.setBeanClass(AnotherClass.class); // 无效
// 2. 修改构造器参数 - 构造器已调用完毕
// beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(...); // 无效
}
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化后");
}
return true;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}@Component
public class UserService {
private String name;
// setter 方法名必须是 setXxx,且 xxx 要和 Bean 名匹配
public void setName(String name) { // 会注入名为 "name" 的 Bean
this.name = name;
}
public void a() {
System.out.println("a.....");
}
public void test() {
System.out.println(name);
}
}public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
applicationContext.getBean("userService", UserService.class).test();
}
}输出结果:
实例化前
BeanDefinition的后置处理
实例化后
初始化前
a.....
初始化后
danny典型的实例场景:
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition,
Class<?> beanType,
String beanName) {
// 场景1:为特定的 Bean 添加元数据
if (beanType.isAnnotationPresent(MyAnnotation.class)) {
// 存储注解信息,供后续后处理器使用
cacheAnnotationInfo(beanName, beanType.getAnnotation(MyAnnotation.class));
}
// 场景2:动态修改注入模式
if (beanDefinition.getAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_NO) {
// 改为按类型自动装配
beanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
}
// 场景3:检查并记录 Bean 定义信息
logBeanDefinitionInfo(beanName, beanDefinition);
}在Spring源码中,AutowiredAnnotationBeanPostProcessor就是一个MergedBeanDefinitionPostProcessor,它的postProcessMergedBeanDefinition()中会去查找注入点,并缓存在AutowiredAnnotationBeanPostProcessor对象的一个Map中(injectionMetadataCache)。
再后面是三级缓存的一个处理,与循环依赖有关,这里我们暂时跳过。接下来就是填充Bean了,对应的方法是:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
实例化后
populateBean方法前面有一些判断,我们先跳过,后面就来到了实例化后处理。
这个方法在上面我们已经实现过了,这里再简单说明下。
也就是说在处理完BeanDefinition后,Spring又设计了一个扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(),比如:
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
UserService userService = (UserService) bean;
userService.test();
}
// true: 继续执行后续的属性填充(populateBean)
// false: 跳过当前bean的属性填充
return true;
}
}上述代码就是对userService所实例化出来的对象进行处理,这个扩展点在Spring框架源码内部的使用相对有限,主要留给开发者进行定制。它最核心的作用是通过返回false来阻止特定bean的属性填充。虽然Spring自身直接使用的地方不多,但在需要精细控制bean初始化流程的场景下,它提供了重要的扩展能力。
再往后面会进行一个依赖注入的处理,这里先明确一些概念的定义。
依赖注入 (Dependency Injection)
广义概念:任何形式的依赖注入,包括自动注入和注解注入
时机:发生在
populateBean()方法中包括:
自动注入 (autowiring)
注解注入 (
@Autowired等)XML显式配置 (
<property>)
BeanPostProcessor 处理的依赖注入
狭义概念:特指通过注解声明的依赖注入
位置:在
populateBean()中,通过InstantiationAwareBeanPostProcessor.postProcessProperties()执行实现类:
AutowiredAnnotationBeanPostProcessor等
自动注入
这里的自动注入指的是Spring的自动注入,不是很重要,并且此功能已经不建议使用了,在@Bean注解的源码中都移除了对应的属性:

当然我们依然可以在XML配置中指定autowrie属性,或者如果不想更换容器,就可以在前面介绍的BeanDefnition的后置处理中修改。
// 处理合并以后的BeanDefinition,此方法在源码中对于在实例化后初始化之前被调用
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 这个地方可以修改BeanDefinition的值,影响后续的步骤,前面的步骤是不受影响的,你比如你改beanClass是没有用的,对象都创建了
if ("userService".equals(beanName)) {
System.out.println("BeanDefinition的后置处理");
// 3. 修改是否自动装配
beanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
}
}@Component
public class UserService {
private OrderService orderService;
public void setOrderService(OrderService orderService) {
this.orderService = orderService;
}
public void test() {
System.out.println(orderService);
}
}@Component
public class OrderService {
}public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
applicationContext.getBean("userService", UserService.class).test();
}
}最后发现打印orderService会有值。当然也可以改成byName。这里我们不进入深入分析,只讲下大概的工作原理:
开启自动注入后,Spring会收集所有的setter并进行调用,如果是byName就根据属性名(setXxx的xxx)去getBean(),如果是类型就根据setter的参数类型getBean()。
下面我们改成byName,验证下:
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化前");
// return new User();
}
return null;
}
// 处理合并以后的BeanDefinition,此方法在源码中对于在实例化后初始化之前被调用
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 这个地方可以修改BeanDefinition的值,影响后续的步骤,前面的步骤是不受影响的,你比如你改beanClass是没有用的,对象都创建了
if ("userService".equals(beanName)) {
beanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
}
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化后");
}
return true;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}@Component
public class UserService {
public void setOrderService(OrderService xxx) {
System.out.println("by name...:" + xxx);
}
public void test() {
System.out.println("xxx");
}
}输出结果:
实例化前
实例化后
by name...:com.hexon.service.OrderService@393671df
初始化前
初始化后
null如set方法改成setOrderServiceX,这样就找不到Bean,就不会调用set方法了,但是也不会报错。但是改成byType,就又会执行setOrderServiceX方法。
这种方法太激进了,目前已经不推荐使用!推荐的是关闭自动注入,在setter方法上加@Autowired,相当于是全自动改成半自动,你指定了才调用。
现代 Spring 开发确实在从"全自动"转向"半自动":
构造器注入:明确依赖,便于测试,支持不可变性
Setter 注入:用于可选依赖,按需配置
避免字段注入:隐藏依赖,难以测试,不灵活(final报错,构造器可以处理)
再后面就是利用BeanPostProcessor依赖注入了,前面讲实例化前时其实还有个SmartInstantiationAwareBeanPostProcessor接口,这里我们先不介绍,后面解决循环依赖可能会讲到。值得注意的是AutowiredAnnotationBeanPostProcessor接口继承了SmartInstantiationAwareBeanPostProcessor接口。
处理属性
这个步骤中,会处理@Autowired、@Resource、@Value等注解,也是通过InstantiationAwareBeanPostProcessor.postProcessProperties()扩展点来实现的。前面学习的InstantiationAwareBeanPostProcessor接口中就有这个方法,我们自己来实现一下:
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化前");
// return new User();
}
return null;
}
// 处理合并以后的BeanDefinition,此方法在源码中对于在实例化后初始化之前被调用
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 这个地方可以修改BeanDefinition的值,影响后续的步骤,前面的步骤是不受影响的,你比如你改beanClass是没有用的,对象都创建了
if ("userService".equals(beanName)) {
beanDefinition.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
}
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("实例化后");
}
return true;
}
// 属性处理
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("处理属性");
// 技术上可以通过MutablePropertyValues实现添加修改属性
MutablePropertyValues mpvs = new MutablePropertyValues(pvs);
// 修改已有的属性值
if (mpvs.contains("password")) {
// 对密码进行加密
String rawPassword = (String) mpvs.getPropertyValue("password").getValue();
// mpvs.add("password", encrypt(rawPassword));
}
// 技术上也可以:通过 MutablePropertyValues 添加新属性,但不推荐:因为 Bean 可能没有对应的字段/setter
// bean.getClass()反射就可以读取所有字段再读取字段的注解,判断有@Autowired就设置值,也就是可以进入依赖注入的处理,但Spring具体如何实现的我们后面学习
}
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if("userService".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}
postProcessProperties有两个默认实现用于处理@Autowired和@Resource,分别对应AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor这两个类。
postProcessProperties方法总结:
技术上可以:通过
MutablePropertyValues添加新属性但不推荐:因为 Bean 可能没有对应的字段/setter
正确用途:
处理注解注入
修改现有属性值
为可选属性提供默认值
风险:随意添加属性可能导致运行时异常或破坏原有配置
关于@Autowired、@Resource、@Value的底层源码,会在后续的依赖注入章节中详解。
再后面就是Spring 依赖检查(Dependency Check)的实现部分,这段代码实现的依赖检查是 Spring XML 配置时代的产物,现代几乎不用。
最后是一个属性赋值。至此,org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean方法我们也看完了。
最后总结下填充Bean:
实例化后
自动注入处理
Spring利用PostProcessor插件机制实现的@Autowired、@Value、@Resource的依赖注入处理
填充bean,后就是初始化Bean,对应的方法:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
后面有一段是循环处理的处理,再最后就是销毁Bean的逻辑,因此整个org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean方法我们也大概读完了。
现在就是关注initializeBean方法内部的逻辑了。此方法内部大概分为:
执行部分Aware回调
初始化前
初始化
初始化后
下面我们一个个分析。
执行Aware
完成了属性赋值之后,Spring会执行一些回调,包括:
BeanNameAware:回传beanName给bean对象。
BeanClassLoaderAware:回传classLoader给bean对象。
BeanFactoryAware:回传beanFactory给对象。
这个很容易理解,我们第一节手写Spring核心就知道了。
@Component
public class UserService implements BeanFactoryAware {
public void test() {
System.out.println("xxx");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println(beanFactory);
}
}初始化前
初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization()。具体的入口方法是:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
此方法6.1版本后增加了过时标记,这个应该是防止外部用户直接调用的一个警告,但是内部还是走这个方法。
最终都是调用postProcessBeforeInitialization方法,也就是最顶层接口BeanPostProcessor的方法,前面我们也自己实现了:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
}利用初始化前,可以对进行了依赖注入之后的Bean进行处理。
在Spring源码中:
InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法,
ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:
EnvironmentAware:回传环境变量
EmbeddedValueResolverAware:回传占位符解析器
ResourceLoaderAware:回传资源加载器
ApplicationEventPublisherAware:回传事件发布器
MessageSourceAware:回传国际化资源
ApplicationStartupAware:回传应用其他监听对象,可忽略
ApplicationContextAware:回传Spring容器ApplicationContext
可以自己调试下InitDestroyAnnotationBeanPostProcessor和ApplicationContextAwareProcessor类的applyBeanPostProcessorsBeforeInitialization方法
初始化
查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
执行BeanDefinition中指定的初始化方法
看到这个源码,其实就知道了下面三种方式执行的顺序:
@PostConstruct
afterPropertiesSet()
@Bean指定的initMethod
public class UserService implements InitializingBean {
@PostConstruct
public void test() {
System.out.println("@PostConstruct...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet...");
}
public void init() {
System.out.println("initMethod...");
}
}@ComponentScan
public class MyConfig {
@Bean(initMethod = "init")
public UserService userService() {
return new UserService();
}
}public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
}
}输出结果:
@PostConstruct...
afterPropertiesSet...
initMethod...初始化后
这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessAfterInitialization(),比如:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象。
总结BeanPostProcessor
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
实例化
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
自动注入
InstantiationAwareBeanPostProcessor.postProcessProperties()
Aware回调
BeanPostProcessor.postProcessBeforeInitialization()
初始化
BeanPostProcessor.postProcessAfterInitialization()