你們都知道,項目啓動的時候,spring讀取xml文件,將配置的bean 或者 註解下的controller service dao所有實例化。而後注入到代碼裏去使用。那麼咱們怎麼本身去獲取某個實例化的bean呢。本身new是沒用的。java
舉個場景,redis
假設我寫了一個類spring
public class A{ @Resource private static ADao aDao; static{ aDao.select(); } public static void getA(){ ... } }
當 別的類裏調用A.getA()的時候,調用的是靜態方法,A並不會實例化,只是初始化,也就是說aDao-null;數據庫
可能會以爲我設定這個A類很奇葩,可是有的場景就是這樣,爲了提升性能,我只容許查庫一次,之後讀取內存。(不放到redis爲了安全),因此就要用只會第一次初始化纔會被執行的靜態代碼塊。編程
這個時候我就須要本身去獲取aDao了。安全
那麼怎麼獲取呢?mybatis
首先咱們要知道幾個問題app
1, aDao已經實例化了,只是在spring容器中,還不知道怎麼去取。ide
2,若是用的mybatis的接口式編程,那麼aDao只是一個接口,他的實現類是MapperFactoryBean,並非自己,性能
<bean id="aDap" class=" .../.../aDao"/>這種寫法是錯誤的。
3, ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
context.getBean("BeanName");
這種作法是日常測試的時候,在不啓動spring的時候的一種加載配置文件實例化bean的方法。
在一個正常啓動的項目中,這樣作是不對的,會使spring從新實例化,從新創建數據庫鏈接池。這至關於重啓一個正在運行的項目,是很嚴重的。
因此咱們要用spring給咱們提供的接口去搞。
方法一:實現BeanFactoryAware接口
代碼以下:
@Service public class BeanUtils implements BeanFactoryAware { // Spring的bean工廠 private static BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory factory) throws BeansException { beanFactory=factory; } public static<T> T getBean(String beanName){ return (T) beanFactory.getBean(beanName); } }
這個類的意思大致這麼幾個
1,實現BeanFactoryAware接口,這個接口可讓咱們在項目啓動後獲取bena工廠的實例,從而爲所欲爲的獲取咱們想要的bean實例。
2,setBeanFactory()方法是用的spring的依賴注入,set方法是三種注入方式之一。這樣實例纔會注入到該類裏。
既然要注入,那麼咱們必須設置BeanUtils這個類也要在項目啓動的時候被spring實例化,我這裏是採用註解的方式@service來實現。
3,靜態getBean方法,這裏方法必須是靜態的,由於你若是本身去new這個BeanUtils類的話,beanFactory是不會被注入進去的。
方法二,很是簡單的一種用法。
ContextLoaderListener.getCurrentWebApplicationContext().getBean ("beanName");
使用 上下文監聽器去獲取上下文,而後獲取bean,這個方法細心的同窗應該能看到,這是上面我講的一種錯誤用法的改變。3, ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");,用一句話概述就是,new是無論用的,從容器中拿出來纔是正道。
關於ContextLoaderListener這個監聽器就很少說了。
這裏只列出兩種,還有幾種方式,也能夠獲取。
若是哪裏解釋的不對,但願大神指點下小弟,畢竟本身摸索,不免會出錯。