Spring框架中Bean的加载和初始化顺序

前言

    在Spring框架中,Bean的加载和初始化过程是一个复杂而细致的过程,涉及多个阶段和扩展点。在我们日常开发中也会用到相关的知识,所以我们必须了解。

1. Spring容器启动

 Spring容器启动时,会扫描配置的包路径并找到所有标注了@Component(以及其他派生注解如@Service@Repository@Controller等)的类,并将其注册为Spring Bean。具体代码看在启动类上的@SpringBootApplication注解。

2. Bean定义阶段

在这个阶段,Spring会根据扫描到的类生成Bean定义(BeanDefinition),并将这些定义存储在容器中。这些定义包含了Bean的配置信息,包括作用域、依赖关系等。

 3. Bean实例化阶段

当需要创建Bean实例时,Spring会进行如下步骤:

(1) 静态代码块

静态代码块在类加载器载入类时执行,只执行一次。

(2)默认代码块

默认代码块(实例初始化块)在每次实例化对象时执行,在构造方法之前执行。

(3)构造函数

构造函数在对象创建时调用,用于初始化对象的基本信息。

4. 属性赋值阶段 

在Bean实例化后,Spring会进行依赖注入,分为以下几种方式:

(1)​​​​​​​@Resource注入或者@Autowired注入

通过@Autowired注解,Spring会自动装配被标注的字段、方法或构造函数。

(2) @Value注入

通过@Value注解,Spring会将外部配置文件中的值注入到Bean的字段中。

5. Aware 接口回调

如果Bean实现了各种Aware接口(如BeanNameAwareBeanFactoryAwareApplicationContextAware等),Spring会在属性赋值后调用相应的方法。 

public class MyBean implements ApplicationContextAware {
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        System.out.println("ApplicationContext set in MyBean");
    }
}
 6. Bean后处理器(BeanPostProcessor

BeanPostProcessor接口的实现类中,Spring允许在初始化方法调用前后对Bean进行自定义修改。这些方法包括:

  • postProcessBeforeInitialization
  • postProcessAfterInitialization
7. 初始化方法
(1)@PostConstruct 注解

在依赖注入完成后,调用标注了@PostConstruct的初始化方法。

@PostConstruct
public void init() {
    System.out.println("PostConstruct of MyBean");
}

(2) 初始化回调(InitializingBean 接口)

如果Bean实现了InitializingBean接口,则会调用其afterPropertiesSet方法。

public class MyBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet of MyBean");
    }
}

 (3) 自定义初始化方法

如果在配置中指定了init-method,Spring会调用这个自定义的初始化方法。

 8. 在容器中使用Bean

在所有的初始化步骤完成之后,Bean就可以在容器中被使用了。 

9. 销毁阶段 

当Spring容器关闭时,会进行Bean的销毁工作。如果Bean实现了DisposableBean接口,或者配置了destroy-method,Spring会调用相应的方法进行清理工作。 

public class MyBean implements DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("destroy of MyBean");
    }
}
总结

整个Bean加载和初始化的顺序如下:

  1. 类加载:静态代码块。
  2. 实例化:默认代码块 -> 构造函数。
  3. 依赖注入@Autowired@Value
  4. Aware接口:各类Aware接口的方法。
  5. BeanPostProcessor:前置处理器。
  6. 初始化方法@PostConstruct -> afterPropertiesSet -> 自定义初始化方法。
  7. BeanPostProcessor:后置处理器。
  8. 使用Bean
  9. 销毁方法DisposableBean -> 自定义销毁方法。

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java程序,可以使用Spring框架提供的BeanPostProcessor接口来查询Bean的加载顺序BeanPostProcessor是一个接口,它提供了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization,这两个方法分别在Bean初始化之前和之后被调用。可以通过实现BeanPostProcessor接口,并在这两个方法输出Bean的名称和加载顺序,来查询Bean的加载顺序。具体步骤如下: 1. 创建一个类,实现BeanPostProcessor接口。 2. 在实现类重写postProcessBeforeInitialization和postProcessAfterInitialization方法,并在方法输出Bean的名称和加载顺序。 3. 将实现类注册到Spring容器,让Spring容器自动调用实现类的方法。 示例代码如下: ```java @Component public class BeanPostProcessorImpl implements BeanPostProcessor { private static final Logger logger = LoggerFactory.getLogger(BeanPostProcessorImpl.class); @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { logger.info("Bean [{}] 开始初始化。", beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { logger.info("Bean [{}] 初始化完成。", beanName); return bean; } } ``` 在上面的代码,我们实现了BeanPostProcessor接口,并在其两个方法输出了Bean的名称和初始化状态。在输出的日志,我们可以根据Bean的初始化状态来判断Bean的加载顺序。例如,如果两个Bean的初始化状态依次为"开始初始化"和"初始化完成",则第一个Bean的加载顺序在第二个Bean之前。 另外,可以通过在Spring配置文件设置debug属性来输出Bean的加载顺序。具体方法是在Spring配置文件添加以下内容: ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" default-lazy-init="false" debug="true"> <!-- 配置Bean --> </beans> ``` 在上面的配置,debug属性设置为true,表示输出调试信息,包括Bean的加载顺序。这种方法比较简单,但是会输出大量的调试信息,很难看清Bean的加载顺序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2024暴富

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值