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

  • 相关阅读:
    解决ssh连接linux系统特别慢的问题
    mysql的InnoDB 数据库引擎TableSpace Exists 问题
    nextcloud私有云盘的部署
    su: 无法设置用户ID: 资源暂时不可用
    oracle静默安装
    mysql update 子查询锁表问题
    mysql导出数据很快,导入很慢
    mysql千万级数据库插入速度和读取速度的调整
    django, CentOS7+nginx(apache)+mod_wsgi+Python+Django
    javascript 重写已有的方法
  • 原文地址:https://www.cnblogs.com/jpfss/p/8421343.html
Copyright © 2011-2022 走看看