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


大家都知道,項目啟動的時候,spring讀取xml文件,將配置的bean 或者 注解下的controller service dao全部實例化。然后注入到代碼里去使用。那么我們怎么自己去獲取某個實例化的bean呢。自己new是沒用的。

舉個場景,

假設我寫了一個類

public class A{

@Resource
private static ADao aDao;
static{
  aDao.select();
}
public static void getA(){
 ...
}
}

當 別的類里調用A.getA()的時候,調用的是靜態方法,A並不會實例化,只是初始化,也就是說aDao-null;

可能會覺得我設定這個A類很奇葩,但是有的場景就是這樣,為了提高性能,我只允許查庫一次,以后讀取內存。(不放到redis為了安全),所以就要用只會第一次初始化才會被執行的靜態代碼塊。

這個時候我就需要自己去獲取aDao了。

那么怎么獲取呢?

首先我們要知道幾個問題

1, aDao已經實例化了,只是在spring容器中,還不知道怎么去取。

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這個監聽器就不多說了。

這里只列出兩種,還有幾種方式,也可以獲取。

如果哪里解釋的不對,希望大神指點下小弟,畢竟自己摸索,難免會出錯。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM