Spring Bean的初始化和销毁方式详解
2016-10-26 22:51
417 查看
最近在项目中需要封装kafka的服务,其中使用到了工厂模式,该模式涉及到了Spring Bean的初始化和销毁,如是研究了一番,总结如下,和大家共勉之
Spring Bean的初始化和销毁Bean有几种方法了?答案是3种
方法一:使用@PostConstruct注解初始化,使用@PreDestroy注解销毁Bean
示例代码如下:
配置文件如下:
<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>
测试结果如下:
方法二:实现InitializingBean, DisposableBean这两个接口,并复写afterPropertiesSet()和destroy()方法
示例代码如下:
方法三:使用init-method和destroy-method配置方法
示例代码如下:
配置文件如下:
<bean id="methodInit" class="com.chhliu.myself.spring.test.MethodInit" init-method="initMethod" destroy-method="destroyMethod"></bean>测试结果如下:
那么三种初始化和销毁Spring Bean的方式就讲完了,那么这三种方式的执行顺序是如何了,我们接着来做个测试
测试代码如下:
测试结果如下:
执行InitAndDestroySeqBean: 构造方法
执行InitAndDestroySeqBean: postConstruct
执行InitAndDestroySeqBean: afterPropertiesSet
执行InitAndDestroySeqBean: init-method
执行InitAndDestroySeqBean: preDestroy
执行InitAndDestroySeqBean: destroy
执行InitAndDestroySeqBean: destroy-method
最后我们得出的结果如下:
1、如果我们在afterPropertiesSet()方法中抛出异常,那么初始化会被终止,不会执行后面的init-method对应的初始化方法
2、Spring中初始化的Bean的类为
Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
3、afterPropertiesSet()方法的效率比init-method高,因为init-method使用的是反射来寻找对应的方法,而afterPropertiesSet()则是直接执行的,相关源码如下:
Spring Bean的初始化和销毁Bean有几种方法了?答案是3种
方法一:使用@PostConstruct注解初始化,使用@PreDestroy注解销毁Bean
示例代码如下:
public class PostConstructInit { @PostConstruct public void PostConstruct() { System.out.println("执行PostConstructInit: PostConstruct"); } @PreDestroy public 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 |
示例代码如下:
public class InitializingDisposableInit implements InitializingBean, DisposableBean { @Override public void destroy() throws Exception { System.out.println("执行InitializingDisposableInit: destroy"); } @Override public 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 |
示例代码如下:
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 |
测试代码如下:
public class InitAndDestroySeqBean implements InitializingBean, DisposableBean { public InitAndDestroySeqBean() { System.out.println("执行InitAndDestroySeqBean: 构造方法"); } @PostConstruct public void postConstruct() { System.out.println("执行InitAndDestroySeqBean: postConstruct"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("执行InitAndDestroySeqBean: afterPropertiesSet"); } public void initMethod() { System.out.println("执行InitAndDestroySeqBean: init-method"); } @PreDestroy public void preDestroy() { System.out.println("执行InitAndDestroySeqBean: preDestroy"); } @Override public 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 和销毁前所做的操作的3种方式
- 关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种
- Spring下的Bean初始化和销毁两种方式
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- Spring bean的初始化和销毁三种方式及优先级
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- 在spring容器中定义初始化和销毁bean前所做的操作,有三种方式
- spring 容器初始化 bean 和销毁前所做的操作定义方式(InitializingBean ,DisposableBean)
- Spring下的Bean初始化和销毁两种方式
- Spring初始化Bean或销毁Bean前执行操作的方式
- Spring中初始化bean和销毁bean的时候执行某个方法的详解
- spring的初始化bean,销毁bean之前的操作详解
- 通过Spring @PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
- Spring容器中bean的初始化和销毁工作
- Spring中配置Bean的初始化和销毁