1. 程式人生 > >Spring Boot 普通類呼叫Bean物件的一種方式

Spring Boot 普通類呼叫Bean物件的一種方式

有時我們有一些特殊的需要,可能要在一個不被Spring管理的普通類中去呼叫Spring管理的bean物件的一些方法,比如一般SpringMVC工程在controller中通過

@Autowired
private TestService testService;

注入TestService 介面就可以呼叫此介面實現類的實現的方法。 
但在一般類中顯然不可以這麼做,注入的 TestService 將會報空指標異常,你無法拿到這個bean,在一般的ssm工程中我們可以通過xml配置把普通類設定成一個bean物件,那麼 TestService 就有效了, 或者使用 ApplicationContext

 直接讀取xml配置中的bean也可以拿到 TestService。`

Spring Boot 已經摒棄了各種繁瑣的xml配置,當然就不再使用xml配置的方式,之前在網上看到一種很簡便的方式,但現在又找不到連結了,這裡做下記錄。

在普通類中定義 ApplicationContext 靜態變數和set方法

    private static ApplicationContext applicationContext;//啟動類set入,呼叫下面set方法

    public static void setApplicationContext(ApplicationContext context) {
        applicationContext = context;
    }

在啟動類中,啟動時事實已經生成 ConfigurableApplicationContext 物件, ConfigurableApplicationContext 是 ApplicationContext 介面的實現,這裡直接傳到普通類的 setApplicationContext 方法就行了

@SpringBootApplication
@ServletComponentScan
public class WxApplication implements EmbeddedServletContainerCustomizer{

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = SpringApplication.run(WxApplication.class, args);
        TestClass.setApplicationContext(applicationContext);
    }
}

由於是靜態變數,類載入時 applicationContext 已經存在,就可獲取到 TestService 了,唯一不好就是靜態變數在伺服器啟動後將一直存在

public class TestClass {

    private static ApplicationContext applicationContext;//啟動類set入,呼叫下面set方法

    public static void setApplicationContext(ApplicationContext context) {
        // TODO Auto-generated method stub
        applicationContext = context;
    }

    public void getBeanTest(){
        TestService testService  = (TestService)applicationContext.getBean(TestService.class);
    }
}

補充: 
在普通 Spring 工程在啟動的時候都會通過 org.springframework.web.context.ContextLoaderListener 監聽器從載入系統資源並管理bean, Spring 提供的 WebApplicationContextUtils 工具類能在請求時獲取到執行時工程的bean,如果看原始碼就可以知道監聽器執行時與 WebApplicationContextUtils 類的關聯

//封裝一下,類的class和請求request為必要引數
public static <T> T getBean(Class<? extends Object> cla,HttpServletRequest request){
        if(request == null){
            return null;
        }
        return (T)WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext()).getBean(cla);//getBean引數可為bean類的.class或直接是bean的Id
    }

//這樣獲取bean
TestService testService= (TestService)getBean(TestService.class, request);