一:实战背景      

     无论是采用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-align:center ; ” 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接口来也可以的.

SpringBean的生命周期扩展实现,前置/后置处理器.

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐