?在spring容器初始化bean和銷毀bean的以前的操作有很多種漆诽,
目前我知道的有:在xml中定義的時(shí)候用init-method
和destory-method
侮攀,還有一種就是定義bean的時(shí)候?qū)崿F(xiàn)DisposableBean
和InitializingBean
這兩個(gè)接口,打開InitializingBean
的源碼:
public interface InitializingBean {
/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception;
}
根據(jù)注解很清楚的可以看出厢拭,afterPropertiesSet()
表示在資源加載完以后兰英,初始化bean之前執(zhí)行的方法,我猜想spring底層應(yīng)該會(huì)在初始化bean的時(shí)候供鸠,應(yīng)該會(huì)使用(bean instanceof InitializingBean)
判斷是不是實(shí)現(xiàn)了這個(gè)接口畦贸,其實(shí)在很多框架中都是這么干的,但是因?yàn)闆](méi)研究過(guò)spring源碼,暫且還不知道底層原理薄坏。這樣我們就可以在初始化的時(shí)候趋厉,做一些自己想要做的事了。
同理胶坠,DisposableBean
就是在一個(gè)bean被銷毀的時(shí)候君账,spring容器會(huì)幫你自動(dòng)執(zhí)行這個(gè)方法,估計(jì)底層原理也是差不多的沈善,對(duì)于一些使用完之后需要釋放資源的bean杈绸,我們都會(huì)實(shí)現(xiàn)這個(gè)接口,或者是配置destory-method
方法矮瘟。源碼也基本是相似的瞳脓,只是把afterPropertiesSet
改為destroy
。
ApplicationContextAware
其實(shí)我們看到Aware就知道是干嘛用的了澈侠,就是屬性注入的劫侧,但是這個(gè)ApplicationContextAware的不同地方在于,實(shí)現(xiàn)了這個(gè)接口的bean哨啃,當(dāng)spring容器初始化的時(shí)候烧栋,會(huì)自動(dòng)的將ApplicationContext注入進(jìn)來(lái):
import org.apache.commons.lang.Validate;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
/**
* applicationContext靜態(tài)化
* 使用了ApplicationContextAware接口的類,如果受spring容器管理的
* 話拳球,那么就會(huì)自動(dòng)的調(diào)用ApplicationContextAware中的setApplicationContext方法
* @author Hotusm
*
*/
@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware,DisposableBean{
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextHolder.applicationContext=applicationContext;
}
//清空applicationContext 設(shè)置其為null
@Override
public void destroy() throws Exception {
SpringContextHolder.clearHolder();
}
//獲得applicationContext
public static ApplicationContext getApplicationContext() {
//assertContextInjected();
return applicationContext;
}
public static void clearHolder(){
applicationContext=null;
}
//獲取Bean
public static <T> T getBean(Class<T> requiredType){
//assertContextInjected();
return (T) getApplicationContext().getBean(requiredType);
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String name){
assertContextInjected();
return (T) getApplicationContext().getBean(name);
}
//判斷application是否為空
public static void assertContextInjected(){
Validate.isTrue(applicationContext==null, "application未注入 审姓,請(qǐng)?jiān)趕pringContext.xml中注入SpringHolder!");
}
}
因?yàn)槲覀冊(cè)谧鲩_發(fā)的時(shí)候,并不是說(shuō)在每一個(gè)地方都能將屬性注入到我們想要的地方去的祝峻,或者需要根據(jù)參數(shù)獲得不同的bean魔吐,比如在Utils使用到dao,我們就不能直接注入了莱找,這個(gè)時(shí)候就是我們需要封裝springContext的時(shí)候了酬姆,而ApplicationContextAware
就起了關(guān)鍵性的作用。
3:還有一種是注解的用法:
在指定方法上加上@PostConstruct
或@PreDestroy
注解來(lái)制定該方法是在初始化之后還是銷毀之前調(diào)用奥溺。