关于Spring启动流程及Bean生命周期梳理
Spring启动流程
在Spring应用程序启动时,Spring框架会完成一系列的初始化工作。具体而言,Spring启动流程如下:
-
加载配置文件:Spring框架首先会读取应用程序中的配置文件。对于基于XML的配置来说,通常是读取applicationContext.xml文件。对于基于Java的配置来说,通常是读取使用@Configuration注解标记的类。
-
创建Bean Definition:每个在配置文件或Java类中定义的Bean都会被转化成相应的Bean Definition对象。
-
创建Bean实例:Spring框架根据Bean Definition对象创建Bean实例。这时会调用Bean类的构造函数,实例化出一个Bean实例。
-
装配Bean:Spring框架会根据配置文件或Java类中的依赖关系,装配出相应的Bean对象。
-
初始化Bean:Spring框架使用initMethod配置或@PostConstruct注解指定的初始化方法来执行Bean的初始化工作。
-
使用Bean:Spring框架将创建好的Bean对象注入到其它Bean中,或将其暴露给外部使用。
-
销毁Bean:当Spring框架检测到应用程序将要关闭时,会调用Bean的销毁方法。
Bean生命周期
在Spring框架中,Bean的生命周期可以分为以下7个阶段:
-
实例化:创建一个Bean实例。
-
属性赋值:将配置文件或Java类中定义的属性注入到Bean实例中。
-
BeanPostProcessor前置处理器:在Bean实例化后、属性赋值前,执行自定义的前置处理器。
-
初始化:执行初始化方法,可以是initMethod属性配置,也可以是使用@PostConstruct注解标记的方法。
-
BeanPostProcessor后置处理器:在Bean初始化完成后,执行自定义的后置处理器。
-
使用:将Bean对象注入到其它Bean中,或将其暴露给外部使用。
-
销毁:当Spring框架检测到应用程序将要关闭时,执行Bean的销毁方法,可以是destroyMethod属性配置,也可以是使用@PreDestroy注解标记的方法。
示例说明
示例一
假设我们要创建一个UserService类,在其中注入一个UserDao类,并在UserService类中通过initMethod方法初始化用户数据。具体实现如下:
public class User {
private int id;
private String name;
private int age;
//...getter和setter方法省略
}
public interface UserDao {
User getUser(int id);
}
public class UserDaoImpl implements UserDao {
@Override
public User getUser(int id) {
//...查询数据库中id为id的用户
return new User();
}
}
public class UserService {
private UserDao userDao;
private List<User> userList;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void init() {
userList = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
userList.add(userDao.getUser(i));
}
}
}
我们在配置文件中将UserDao注入到UserService中,并指定UserService中的init方法为初始化方法。具体配置如下:
<bean id="userDao" class="com.example.UserDaoImpl" />
<bean id="userService" class="com.example.UserService">
<property name="userDao" ref="userDao" />
<property name="initMethod" value="init" />
</bean>
在应用程序启动时,Spring框架会按照上述流程,创建UserService对象,并通过它的init方法初始化用户数据。
示例二
假设我们要创建一个自定义的BeanPostProcessor前置处理器,在Bean初始化前,打印出Bean的名称和类名。具体实现如下:
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Before initialization, beanName=" + beanName + ", beanClass=" + bean.getClass().getName());
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
在配置文件中,我们将该处理器注入到Spring容器中。具体配置如下:
<bean id="myBeanPostProcessor" class="com.example.MyBeanPostProcessor" />
在应用程序启动时,Spring框架会自动执行该处理器,并在每个Bean初始化前打印出Bean的名称和类名。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于Spring启动流程及Bean生命周期梳理 - Python技术站