1. 程式人生 > >SpringBoot獲取Spring容器中的Bean

SpringBoot獲取Spring容器中的Bean

一:實戰背景      

     無論是採用XML檔案的方式還是JAVA配置的方式。都是配置豆嘛,那麼如何獲取春天容器中的Bean(Spring容器自身的Bean和我們自己配置的Bean)的吶?並且以表格展示一下,統一一下數量吧。

二:環境搭建

      SpringBoot框架,Thymeleaf,BootStrap,IDEA,Maven的,Ajax前後臺互動,即可。

三:實驗環節

      1.通過ConfigurableApplicationContext這個介面來獲取,繼承ApplicationContext。定義了一些設定上下文,監聽容器,重新整理容器的操作。可以獲取使用了特定註解的Bean,容器裡面所有的Bean的。

     原始碼如下:

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
    String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
String ENVIRONMENT_BEAN_NAME = "environment"
; String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties"; String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment"; void setId(String var1); void setParent(ApplicationContext var1); void setEnvironment(ConfigurableEnvironment var1); ConfigurableEnvironment getEnvironment(); void addBeanFactoryPostProcessor(BeanFactoryPostProcessor var1);
void addApplicationListener(ApplicationListener<?> var1); void addProtocolResolver(ProtocolResolver var1); void refresh() throws BeansException, IllegalStateException; void registerShutdownHook(); void close(); boolean isActive(); ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException; }

ContextConfig配置類

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;@Configuration
public class ContextConfig {
    @Autowired
private ConfigurableApplicationContext context;
    public int getCount(){
        return context.getBeanDefinitionCount();
}
    public String[] getContext(){
        return context.getBeanDefinitionNames();
}
}

 BeanController。一個Map存放資料。Ajax接收資料。

import com.lx.myvideo.config.ContextConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;@RestController
public class BeansController {
    @Autowired
private ContextConfig contextConfig;
@RequestMapping("/getBeans")
    public Map showBeans(){
        Map<String,Object> map=new HashMap();
map.put("count",contextConfig.getCount());
        return map;
}
}

PageController

import com.lx.myvideo.config.ContextConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;@Controller
public class PageController {
    @Autowired
private ContextConfig contextConfig;
    private static final String TO_PATH="beans";
@RequestMapping("/beans")
    public ModelAndView showBeans(){
         String[] beans=contextConfig.getContext();
ModelAndView view=new ModelAndView();
view.addObject("beansArray",beans);
view.setViewName(TO_PATH);
         return view;
}
}
beans.html(前臺向後臺請求資料(不帶資料),後臺返回給前臺JSON格式的資料,就是Bean的個數嘛。)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
<head>
    <meta charset="UTF-8">
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" >
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
        <title>【獲取Spring容器的Bean】</title>
        <meta name="keywords" content="Beans">
        <meta name="description" content="Beans">
        <link rel="icon" th:href="@{/images/newlogo.png}" />
        <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}"  media="all">
        <link rel="stylesheet" th:href="@{/font-awesome/css/font-awesome.min.css}" />
        <script th:src="@{/js/jquery-1.7.1.min.js}"></script>
        <style type="text/css">
*{
                 margin:0;
padding:0;
}
             .beanbtn{
                 position: relative;
left: 737px;
top: -54px;
}
             #count{
                width:350px;
position:relative;
left:390px;
top:-20px;
}
             #bean{
               width:80%;
margin: 0 auto;
}
        </style>
</head>
<body>
     <div style="width:100%;height:100px;" align="center">
            <h1 style="color:#985f0d;">獲取Spring容器中的Bean</h1>
     </div>
     <div >
             <input type="text" class="form-control" id="count"  value="" readonly />
         <div class="beanbtn">
             <button type="button" class="btn btn-primary" id="getBeans">獲取當前容器中的Bean</button>
         </div>
     </div>
     <div class="bs-example" data-example-id="striped-table"  id="bean" >
         <table class="table table-bordered table-hover">
             <thead>
               <tr>
                   <th style="text-align:center;" scope="row">序號</th>
                   <th style="text-align:center;">BeanName</th>
               </tr>
             </thead>
             <tbody>
               <tr th:each="array:${beansArray}">
                   <th style="text-align:center;" th:text="${arrayStat.index+1}"></th>
                   <th th:text="${array}"></th>
               </tr>
             </tbody>
         </table>
     </div>
     <script>
$(function(){
             $('#getBeans').click(function(){
                  $.ajax({
                    url:'/getBeans',
type:'post',
data:{},
dataType:'json',
success:function(data){
                       $("#count").val("當前容器中的Bean資料量為:"+data.count);
},
error:function(data){
                        alert("獲取資料失敗!");
}
                  });
});
});
</script>
</body>
</html>

2.細節環節

  Thymeleaf在遍歷陣列的時候,比如我這裡是字串[]的陣列,要設計到索引號的問題。有些特殊。在前面的陣列接受後臺的之後加Stat的就可以了。小寫的不可以。要報不識別的錯誤的。

<th style = text-aligncenter ; th :text = “$ {arrayStat.index + 1}” > </ th>

3.執行結果


點選按鈕獲取Bean的資料量。



4.當然了能獲取Bean的名稱和數量,那麼Bean的型別和包名也能獲取。包括@Controller,@Service等都是可以獲取的。

例如獲取@Controller註解類的個數。

MyStringUtil

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;@Configuration
@Component
public class MySpringUtil implements ApplicationContextAware {
    /** 宣告一個ApplicationContext*/
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(MySpringUtil.applicationContext==null){
            MySpringUtil.applicationContext=applicationContext;
}
        System.out.println("---獲取到applicationContext---");
}
    /** 獲取ApplicationContext*/
public static ApplicationContext getApplicationContext(){
        return applicationContext;
}
    /** 統計controller的數量*/
public static String[] controllers(Class<? extends Annotation> clazz){
        return applicationContext.getBeanNamesForAnnotation(clazz);
}
}

然後在使用的類裡面依賴注入使用@Autowired型別注入即可。


當時使用了ApplicationContextAware介面來也可以的.