在sPRing容器初始化bean和銷毀bean的以前的操作有很多種,
目前我知道的有:在xml中定義的時候用init-method和destory-method,還有一種就是定義bean的時候實現DisposableBean和InitializingBean 這兩個接口,打開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;}
根據注解很清楚的可以看出,afterPropertiesSet()表示在資源加載完以后,初始化bean之前執行的方法,我猜想spring底層應該會在初始化bean的時候,應該會使用(bean instanceof InitializingBean)判斷是不是實現了這個接口,其實在很多框架中都是這么干的,但是因為沒研究過spring源碼,暫且還不知道底層原理。這樣我們就可以在初始化的時候,做一些自己想要做的事了。
同理,DisposableBean就是在一個bean被銷毀的時候,spring容器會幫你自動執行這個方法,估計底層原理也是差不多的,對于一些使用完之后需要釋放資源的bean,我們都會實現這個接口,或者是配置destory-method方法。源碼也基本是相似的,只是把afterPropertiesSet改為destroy。
ApplicationContextAware
其實我們看到---Aware就知道是干嘛用的了,就是屬性注入的,但是這個ApplicationContextAware的不同地方在于,實現了這個接口的bean,當spring容器初始化的時候,會自動的將ApplicationContext注入進來:
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靜態化 * 使用了ApplicationContextAware接口的類,如果受spring容器管理的 * 話,那么就會自動的調用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 設置其為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未注入 ,請在springContext.xml中注入SpringHolder!"); } }
因為我們在做開發的時候,并不是說在每一個地方都能將屬性注入到我們想要的地方去的,比如在Utils使用到dao,我們就不能直接注入了,這個時候就是我們需要封裝springContext的時候了,而ApplicationContextAware就起了關鍵性的作用。
新聞熱點
疑難解答