zoukankan      html  css  js  c++  java
  • spring boot 的 ApplicationContext 及 getbean

    在spring中,我们通过如下代码取得一个spring托管类:

    1. ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");  
    2. ac.getBean("beanId"); 

    在spring boot中,我参考了如下三篇文章:


    让非Spring管理的类获得一个Bean

    http://blog.sina.com.cn/s/blog_72ef7bea0102wcvk.htmlblog.sina.com.cn/s/blog_72ef7bea0102wcvk.html


    Spring Boot普通类调用bean

    http://blog.csdn.net/u014695188/article/details/52396880


    SpringBoot-获取上下文

    http://www.2cto.com/kf/201701/582935.html


    做了一些实践。


    首先,我们需要一个媒介,来取得AppicationContext——SpringUtil

    这个类有两种方式:

    1. 实现ApplicationContextAware接口

    @Component
    public class SpringUtil implements ApplicationContextAware {

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ApplicationContext applicationContext = <span class="hljs-keyword">null</span>;</br>
    

    // 非@import显式注入,@Component是必须的,且该类必须与main同包或子包

    // 若非同包或子包,则需手动import 注入,有没有@Component都一样

    // 可复制到Test同包测试

    <span class="hljs-annotation">@Override</span></br>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setApplicationContext</span><span class="hljs-params">(ApplicationContext applicationContext)</span> <span class="hljs-keyword">throws</span> BeansException </span>{</br>
        <span class="hljs-keyword">if</span>(SpringUtil.applicationContext == <span class="hljs-keyword">null</span>){</br>
            SpringUtil.applicationContext  = applicationContext;</br>
        }</br>
        System.out.println(<span class="hljs-string">"---------------com.ilex.jiutou.util.Test.Main.SubPackage.SpringUtil---------------"</span>);</br>
    }</br></br>
    
    <span class="hljs-comment">//获取applicationContext</span></br>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ApplicationContext <span class="hljs-title">getApplicationContext</span><span class="hljs-params">()</span> </span>{</br>
        <span class="hljs-keyword">return</span> applicationContext;</br>
    }</br>
    

    //通过name获取 Bean.
    public static Object getBean(String name){
    return getApplicationContext().getBean(name);

    }</br></br>
    
    <span class="hljs-comment">//通过class获取Bean.</span></br>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> &lt;T&gt; <span class="hljs-function">T <span class="hljs-title">getBean</span><span class="hljs-params">(Class&lt;T&gt; clazz)</span></span>{</br>
        <span class="hljs-keyword">return</span> getApplicationContext().getBean(clazz);</br>
    }</br></br>
    
    <span class="hljs-comment">//通过name,以及Clazz返回指定的Bean</span></br>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> &lt;T&gt; <span class="hljs-function">T <span class="hljs-title">getBean</span><span class="hljs-params">(String name,Class&lt;T&gt; clazz)</span></span>{</br>
        <span class="hljs-keyword">return</span> getApplicationContext().getBean(name, clazz);</br>
    }</br>
    

    }





    需要被spring注入,覆写setApplicationContext

    2. 普通类


    //@Component  在不可扫描区域,且不需要注入,作为一个普通的util类
    public class SpringUtil{


    private static ApplicationContext applicationContext = null;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setApplicationContext</span><span class="hljs-params">(ApplicationContext applicationContext)</span></span>{</br>
        <span class="hljs-keyword">if</span>(SpringUtil.applicationContext == <span class="hljs-keyword">null</span>){</br>
            SpringUtil.applicationContext  = applicationContext;</br>
        }</br></br>
    
    }</br></br>
    
    <span class="hljs-comment">//获取applicationContext</span></br>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ApplicationContext <span class="hljs-title">getApplicationContext</span><span class="hljs-params">()</span> </span>{</br>
        <span class="hljs-keyword">return</span> applicationContext;</br>
    }</br></br>
    
    <span class="hljs-comment">//通过name获取 Bean.</span></br>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title">getBean</span><span class="hljs-params">(String name)</span></span>{</br>
        <span class="hljs-keyword">return</span> getApplicationContext().getBean(name);</br></br>
    
    }</br>
    
    <span class="hljs-comment">//通过class获取Bean.</span></br>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> &lt;T&gt; <span class="hljs-function">T <span class="hljs-title">getBean</span><span class="hljs-params">(Class&lt;T&gt; clazz)</span></span>{</br>
        <span class="hljs-keyword">return</span> getApplicationContext().getBean(clazz);</br>
    }</br>
    
    <span class="hljs-comment">//通过name,以及Clazz返回指定的Bean</span></br>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> &lt;T&gt; <span class="hljs-function">T <span class="hljs-title">getBean</span><span class="hljs-params">(String name,Class&lt;T&gt; clazz)</span></span>{</br>
        <span class="hljs-keyword">return</span> getApplicationContext().getBean(name, clazz);</br>
    }</br>
    

    }





    不需要被注入,但需要手动调用

    主函数

    @SpringBootApplication
    @Import(value={UserFooterService.class})
    public class Test {
        public static void main(String[] args) {
            ApplicationContext ctx = SpringApplication.run(Test.class, args);
    
    <span class="hljs-comment">//    SpringUtil.setApplicationContext(ctx);  这个对应于AnoStatic</span></br></br>
    
        String[] beanNames =  ctx.getBeanDefinitionNames();</br>
        System.out.println(<span class="hljs-string">"beanNames个数:"</span>+beanNames.length);</br>
        <span class="hljs-keyword">for</span>(String bn:beanNames){</br>
            System.out.println(bn);</br>
        }</br></br>
    
        <span class="hljs-comment">// 测试加载UserFooterService</span></br>
        UserFooterService userFooterService = (UserFooterService) SpringUtil.getBean(UserFooterService.class);</br>
        List&lt;Map&lt;String,Object&gt;&gt; list = userFooterService.hotTopic(<span class="hljs-string">"0"</span>, <span class="hljs-string">"5"</span>);</br>
        System.out.println(list.toString());</br></br>
    
        <span class="hljs-comment">// 测试加载SpringUtil</span></br>
        SpringUtil springUtil = (SpringUtil)SpringUtil.getBean(SpringUtil.class);</br>
        System.out.println(springUtil);</br>
    }</br></br>
    

    // @Bean

    // public SpringUtil springUtil() {

    // return new SpringUtil();

    // }

    }





    UserFooterService是一个业务类,这里不榕树


    建立如下的测试结构:


    Main/Test 主函数

    AnoStatic/SpringUtil  普通类

    Main/SubPackage/SpringUtil 实现ApplicationContextAware,但为主函数子包

    NonSubPackage/SpringUtil 实现ApplicationContextAware,但非主函数子包和同包



    SpringUtil注入方式有三种,在参考的三篇博客均有说明,在此仅总结:

    1. 类与SpringBootApplication同包或子包,此在ComponentScan的扫描范围之内,在类上@Component注解即可,会被自动注入;

    2. 无论位置,都可通过在主函数用@import或@bean来手动注入。


    第一种SpringUtil方式必须被spring注入,否则会报

    Exception in thread "main" java.lang.NullPointerException

    at com.ilex.jiutou.util.Test.NonSubPackage.SpringUtil.getBean(SpringUtil.java:40)

    at com.ilex.jiutou.util.Test.Main.Test.main(Test.java:34)


    表示applicationContext获取失败


    第二种方式,SpringUtil可被注入可不被注入

    当不注入时,主函数这一段:

            // 测试加载SpringUtil
            SpringUtil springUtil = (SpringUtil)SpringUtil.getBean(SpringUtil.class);
            System.out.println(springUtil);

    报错:

    No qualifying bean of type [**.Test.AnoStatic.SpringUtil

  • 相关阅读:
    Dot Net WinForm 控件开发 (七) 为属性提下拉式属性编辑器
    WinForm 程序的界面多语言切换
    c#遍历HashTable
    Dot Net WinForm 控件开发 (三) 自定义类型的属性需要自定义类型转换器
    Dot Net WinForm 控件开发 (六) 为属性提供弹出式编辑对话框
    Dot Net WinForm 控件开发 (一) 写一个最简单的控件
    Dot Net WinForm 控件开发 (四) 设置属性的默认值
    Dot Net WinForm 控件开发 (二) 给控件来点描述信息
    Dot Net WinForm 控件开发 (八) 调试控件的设计时行为
    Dot Net WinForm 控件开发 (五) 复杂属性的子属性
  • 原文地址:https://www.cnblogs.com/jpfss/p/8421343.html
Copyright © 2011-2022 走看看