spring 中 init-method 和 destroy-method 的使用方式

init-method:bean 构造器执行之后执行

destroy-method:bean 被销毁之前执行


方式一:在 XML 中配置

<!-- 测试 destroy 和 init -->
	<bean name="init_destroy" class="com.test.spring.bean.TestInitMethodAndDestroyMethod"
		init-method="initMthod" destroy-method="destroyMethod" />

package com.test.spring.bean;

public class TestInitMethodAndDestroyMethod {

	public void initMthod(){
		System.out.println("TestInitMethodAndDestroyMethod initMthod begin..");
	}
	
	public TestInitMethodAndDestroyMethod() {
		System.out.println("TestInitMethodAndDestroyMethod 实例化..");
	}
	
	public void destroyMethod(){
		System.out.println("TestInitMethodAndDestroyMethod destroyMethod begin..");
	}
}

方式二:使用注解


package com.test.spring.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class TestInitMethodAndDestroyMethod {

	@PostConstruct
	public void initMthod(){
		System.out.println("TestInitMethodAndDestroyMethod initMthod begin..");
	}
	
	public TestInitMethodAndDestroyMethod() {
		System.out.println("TestInitMethodAndDestroyMethod 实例化..");
	}
	
	@PreDestroy
	public void destroyMethod(){
		System.out.println("TestInitMethodAndDestroyMethod destroyMethod begin..");
	}
}



方式三:通过 bean 实现接口


package com.test.spring.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class TestInitMethodAndDestroyMethod implements InitializingBean,DisposableBean {

	/*@PostConstruct
	public void initMthod(){
		System.out.println("TestInitMethodAndDestroyMethod initMthod begin..");
	}*/
	
	public TestInitMethodAndDestroyMethod() {
		System.out.println("TestInitMethodAndDestroyMethod 实例化..");
	}
	
	/*@PreDestroy
	public void destroyMethod(){
		System.out.println("TestInitMethodAndDestroyMethod destroyMethod begin..");
	}*/

	@Override
	public void destroy() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("TestInitMethodAndDestroyMethod destroy begin..");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		System.out.println("TestInitMethodAndDestroyMethod afterPropertiesSet begin..");
	}
}



方式一和方式二相同,方式三的执行顺序

先执行afterPropertiesSet(),

后执行initMethod()


通过查看 AbstractAutowireCapableBeanFactory 的 

invokeInitMethods
方法,


      protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
            throws Throwable {
        //判断该bean是否实现了实现了InitializingBean接口,如果实现了InitializingBean接口,则只掉调用bean的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 {
                            //直接调用afterPropertiesSet
                            ((InitializingBean) bean).afterPropertiesSet();
                            return null;
                        }
                    },getAccessControlContext());
                } catch (PrivilegedActionException pae) {
                    throw pae.getException();
                }
            }                
            else {
                //直接调用afterPropertiesSet
                ((InitializingBean) bean).afterPropertiesSet();
            }
        }
        if (mbd != null) {
            String initMethodName = mbd.getInitMethodName();
            //判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method
            if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                    //进一步查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

总结:

1:spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过

init-method指定,两种方式可以同时使用


2:实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是

init-method方式消除了对spring的依赖


3:如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。


参考:http://blog.csdn.net/lovesomnus/article/details/50158761#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值