Spring Bean的初始化和销毁方式详解
来源:互联网 发布:firebird sql server 编辑:程序博客网 时间:2024/06/11 07:35
最近在项目中需要封装kafka的服务,其中使用到了工厂模式,该模式涉及到了Spring Bean的初始化和销毁,如是研究了一番,总结如下,和大家共勉之
Spring Bean的初始化和销毁Bean有几种方法了?答案是3种
方法一:使用@PostConstruct注解初始化,使用@PreDestroy注解销毁Bean
示例代码如下:
public class PostConstructInit {@PostConstructpublic void PostConstruct() {System.out.println("执行PostConstructInit: PostConstruct");}@PreDestroypublic void PreDestory(){System.out.println("执行PostConstructInit: PreDestory");}public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");context.close();}}
配置文件如下:
<context:annotation-config/><context:component-scan base-package="com.chhliu.myself.spring.test"></context:component-scan><bean id="postConstructor" class="com.chhliu.myself.spring.test.PostConstructInit"></bean>
测试结果如下:
执行PostConstructInit: PostConstruct
执行PostConstructInit: PreDestory
方法二:实现InitializingBean, DisposableBean这两个接口,并复写afterPropertiesSet()和destroy()方法
示例代码如下:
public class InitializingDisposableInit implements InitializingBean,DisposableBean {@Overridepublic void destroy() throws Exception {System.out.println("执行InitializingDisposableInit: destroy");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("执行InitializingDisposableInit: afterPropertiesSet");}public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans-impl.xml");context.close();}}测试结果如下:
执行InitializingDisposableInit: afterPropertiesSet
执行InitializingDisposableInit: destroy
方法三:使用init-method和destroy-method配置方法
示例代码如下:
public class MethodInit {public void initMethod() {System.out.println("执行MethodInit: init-method");}public void destroyMethod() {System.out.println("执行MethodInit: destroy-method");}public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans-method.xml");context.close();}}
配置文件如下:
<bean id="methodInit" class="com.chhliu.myself.spring.test.MethodInit" init-method="initMethod" destroy-method="destroyMethod"></bean>测试结果如下:
执行MethodInit: init-method
执行MethodInit: destroy-method
那么三种初始化和销毁Spring Bean的方式就讲完了,那么这三种方式的执行顺序是如何了,我们接着来做个测试
测试代码如下:
public class InitAndDestroySeqBean implements InitializingBean, DisposableBean {public InitAndDestroySeqBean() {System.out.println("执行InitAndDestroySeqBean: 构造方法");}@PostConstructpublic void postConstruct() {System.out.println("执行InitAndDestroySeqBean: postConstruct");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("执行InitAndDestroySeqBean: afterPropertiesSet");}public void initMethod() {System.out.println("执行InitAndDestroySeqBean: init-method");}@PreDestroypublic void preDestroy() {System.out.println("执行InitAndDestroySeqBean: preDestroy");}@Overridepublic void destroy() throws Exception {System.out.println("执行InitAndDestroySeqBean: destroy");}public void destroyMethod() {System.out.println("执行InitAndDestroySeqBean: destroy-method");}public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");context.close();}}
测试结果如下:
执行InitAndDestroySeqBean: 构造方法执行InitAndDestroySeqBean: postConstruct执行InitAndDestroySeqBean: afterPropertiesSet执行InitAndDestroySeqBean: init-method执行InitAndDestroySeqBean: preDestroy执行InitAndDestroySeqBean: destroy执行InitAndDestroySeqBean: destroy-method
最后我们得出的结果如下:
初始化顺序:Constructor > @PostConstruct >InitializingBean > init-method销毁的顺序如下:@PreDestroy > DisposableBean > destroy-method最后,我们总结下这几种方式的特点
1、如果我们在afterPropertiesSet()方法中抛出异常,那么初始化会被终止,不会执行后面的init-method对应的初始化方法
2、Spring中初始化的Bean的类为
Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
3、afterPropertiesSet()方法的效率比init-method高,因为init-method使用的是反射来寻找对应的方法,而afterPropertiesSet()则是直接执行的,相关源码如下:
init-method:String initMethodName = mbd.getInitMethodName();final Method initMethod = (mbd.isNonPublicAccessAllowed() ?BeanUtils.findMethod(bean.getClass(), initMethodName) :ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));从上面的代码可以看出,使用的是放射方式afterPropertiesSet():protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)throws Throwable {// 如果存在afterPropertiesSet方法且实例是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(new PrivilegedExceptionAction<Object>() {public Object run() throws Exception {((InitializingBean) bean).afterPropertiesSet();return null;}}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();}}}4、init-method只能是无参无返回的public方法
- Spring Bean的初始化和销毁方式详解
- Spring Bean的初始化和销毁方式详解(转载)
- Spring下的Bean初始化和销毁两种方式
- Spring下的Bean初始化和销毁两种方式
- Spring bean的初始化和销毁
- Spring Bean的初始化和销毁
- spring初始化和销毁bean
- spring bean初始化和销毁
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring bean 的初始化和销毁的三种方式和执行顺序
- spring 容器初始化 bean 和销毁前所做的操作定义方式(InitializingBean ,DisposableBean)
- 关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种
- Spring bean的初始化和销毁三种方式及优先级
- 【Spring】Spring常用配置-Bean的初始化和销毁(生命周期)
- Bean的初始化和销毁
- Mycat安装
- 微服务(Microservices)
- CODEVS 1014装箱问题
- glmis项目工作日志2_增加登录界面_将drawerlayout改为挤压滑动
- MySQL 4.1/5.0/5.1/5.5/5.6/5.7各版本的主要区别
- Spring Bean的初始化和销毁方式详解
- 区块链知识库
- C++ 萃取
- Redmine 配置QQ企业邮箱免费版发送通知邮件的配置(测试通过)
- 嵌入式开发第63日(linux内核模块之设备驱动:模块传参)
- Win7下安装Visual Studio2015编写VC++,遇到无法找到ucrtbased.dll的问题
- 取消按钮的一个处理办法
- [COGS272][NOI1998] 免费馅饼(dp)
- 微服务(厉害啦)