北京 工业网站建设公司,网站建设 项目经验,wordpress美图模板,单页营销式网站模板下载前言
Java 中的公共类称之为Java Bean#xff0c;而 Spring 中的 Bean 指的是将对象的生命周期#xff0c;交给Spring IoC 容器来管理的对象。所以 Spring 中的 Bean 对象在使用时#xff0c;无需通过 new 来创建对象#xff0c;只需要通过 DI#xff08;依赖注入#x…前言
Java 中的公共类称之为Java Bean而 Spring 中的 Bean 指的是将对象的生命周期交给Spring IoC 容器来管理的对象。所以 Spring 中的 Bean 对象在使用时无需通过 new 来创建对象只需要通过 DI依赖注入从 Spring 中取出要使用的对象即可。
在Spring框架中单实例Bean的初始化和销毁过程有这样的执行顺序
初始化顺序PostConstruct → InitializingBean → init-method 销毁顺序PreDestroy → DisposableBean → destroy-method
在初始化Bean时PostConstruct注解方法会首先被执行然后是实现InitializingBean接口的afterPropertiesSet方法最后是init-method指定的方法。
在销毁Bean时PreDestroy注解方法会首先被执行然后是实现DisposableBean接口的destroy方法最后是destroy-method指定的方法。
简单总结一下Spring Bean生命周期的流程
实例化通过构造器方法设置Bean的属性通过setter方法调用Bean的初始化方法PostConstruct、afterPropertiesSet方法或者init-method指定的方法Bean可以被应用程序使用当容器关闭时调用Bean的销毁方法PreDestroy、destroy方法或者destroy-method指定的方法。
1.Bean生命周期
Spring 中 Bean 的生命周期是指Bean 在 SpringIoC中从创建到销毁的整个过程。 Spring 中 Bean 的生命周期主要包含以下 5 部分
实例化为 Bean 分配内存空间设置属性将当前类依赖的 Bean 属性进行注入和装配初始化 执行各种通知执行初始化的前置方法执行初始化方法执行初始化的后置方法。使用 Bean在程序中使用 Bean 对象销毁 Bean将 Bean 对象进行销毁操作。
需要注意的是“实例化”和“初始化”是两个完全不同的过程千万不要搞混实例化只是给 Bean 分配了内存空间而初始化则是将程序的执行权从系统级别转换到用户级别并开始执行用户添加的业务代码。
2.代码演示
因为 Spring Boot 是基于 Spring 创建的所以 Bean 在 Spring 或 Spring Boot 中的行为都是一致的接下来我们使用代码的方式在 Spring Boot 中演示一下 Bean 的生命周期。
首先我们创建一个 Bean 对象起名为 BeanLifecycleComponent名称可以自己指定
Component
public class BeanLifecycleComponent implements BeanNameAware {public void setBeanName(String s) {System.out.println(执行 BeanName 的通知方法);}PostConstructpublic void postConstruct() {System.out.println(执行初始化方法);}public void use() {System.out.println(使用 Bean);}PreDestroypublic void preDestroy() {System.out.println(执行销毁的方法);}
}
然后我们创建一个 MyBeanPostProcessor 类实现初始化的前置方法和初始化的后置方法
Component
public class MyBeanPostProcessor implements BeanPostProcessor {Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals(beanLifecycleComponent)) {System.out.println(执行初始化前置方法...);}return bean;}Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (beanName.equals(beanLifecycleComponent)) {System.out.println(执行初始化后置方法...);}return bean;}
}
注意初始化的前置方法和后置方法是为所有 Bean 服务的而非为某一个 Bean 服务的所以这两个方法不能写在某个具体的 Bean 中要创建一个单独的类来执行否则这两个方法不会执行。
最后在 Spring Boot 的启动类中获取 Bean
SpringBootApplication
public class SpringbootDay01Application {public static void main(String[] args) {//加载上下文环境ConfigurableApplicationContext context SpringApplication.run(SpringbootDay01Application.class, args);// 获取BeanBeanLifecycleComponent component context.getBean(BeanLifecycleComponent.class);// 使用Beancomponent.use();// 停止Spring Boot服务context.close();}}
上面程序的执行结果输出 问题能不能先执行初始化再执行设置属性呢也就是将生命周期中的步骤 2 和步骤 3 的执行顺序交换一下 答案是否定的。
比如以下代码的执行
Controller
public class UserController {Resourceprivate UserService userService;PostConstruct // 初始化方法public void postConstruct() {userService.sayHello();}
}
此时如果先执行步骤 2先将 UserService 注入到当前类再调用步骤 3 执行初始化那么程序的执行是正常的。如果将交换步骤 2 和步骤 3 的执行顺序那么程序执行就会报错空指针异常所以 Bean 的生命周期顺序必须是上面的顺序。