spring-如何在項目啓動的狀況下獲取Bean實例

你們都知道,項目啓動的時候,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這個監聽器就很少說了。

這裏只列出兩種,還有幾種方式,也能夠獲取。

若是哪裏解釋的不對,但願大神指點下小弟,畢竟本身摸索,不免會出錯。

相關文章
相關標籤/搜索