在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


spring boot 的 ApplicationContext 及 getbean的更多相关文章

  1. Spring Boot 获取ApplicationContext

    package com.demo; import org.springframework.beans.BeansException; import org.springframework.contex ...

  2. 曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean definition的?

    写在前面的话 相关背景及资源: 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享 工程代码地址 思维导图地址 工程结构图: 大 ...

  3. spring boot: 中文显示乱码,在applicationContext里面配置

    spring boot: 中文显示乱码,在applicationContext里面配置 applicationContext.properties ########################## ...

  4. spring boot启动报错Error starting ApplicationContext(未能配置数据源)

    主要错误:Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource c ...

  5. Spring Boot -- 启动流程分析之ApplicationContext 中

    上一节我们已经分析到AbsractApplicationContext类refresh方法中的postProcessBeanFactory方法,在分析registerBeanPostProcessor ...

  6. Running Dubbo On Spring Boot

    Dubbo(http://dubbo.io/) 是阿里的开源的一款分布式服务框架.而Spring Boot则是Spring社区这两年致力于打造的简化Java配置的微服务框架. 利用他们各自优势,配置到 ...

  7. How Spring Boot Autoconfiguration Magic Works--转

    原文地址:https://dzone.com/articles/how-springboot-autoconfiguration-magic-works In my previous post &qu ...

  8. How to use JDBC-Authentication of Spring Boot/Spring Security with Flyway

    java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...

  9. Spring boot将配置属性注入到bean类中

    一.@ConfigurationProperties注解的使用 看配置文件,我的是yaml格式的配置: // file application.yml my: servers: - dev.bar.c ...

随机推荐

  1. springboot实现转发和重定向

    1.转发     方式一:使用 "forword" 关键字(不是指java关键字),注意:类的注解不能使用@RestController 要用@Controller @Reques ...

  2. mysql 一次性插入的数据量过大报错max_allowed_packet解决方法

    查询: show VARIABLES like ‘%max_allowed_packet%‘; 记录下数字(默认是一个7位) 执行语句: ; 重启服务 再查询 该数字 ,如果没变,则修改mysql的m ...

  3. mysql联表查询,使用phpStudy自带的

    一.内联结.外联结.左联结.右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结.2.外联结:分为外左 ...

  4. Vue-element 的 resetFields of undefined报错

    触发场景:添加表单弹框,当我信息保存成功后会报 [Vue warn]: Error in event handler for "click": "TypeError: C ...

  5. VS2010-MFC(对话框:为控件添加消息处理函数)

    转自:http://www.jizhuomi.com/software/156.html MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消息处理函数处理.比如我们点击 ...

  6. quatz调度-手动终止线程(1) 创建触发器,线程执行完毕后添加到cleaner list

    import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException;impor ...

  7. python实现批量修改服务器密码

    需求:机房.线上有多台主机,为了保障安全,需要定期修改密码.若手动修改,费时费力易出错. 程序应该满足如下需求 : 1.在现有的excel密码表格,在最后一个字段后面生成新的密码,另存为一个新的exc ...

  8. 编程之法:面试和算法心得(字符串包含java实现)

    内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 给定两个分别由字母组成的字符串A和字符串B,字符串B的长度比字符串A短.请问,如何最快地判断字符串B中所有字母是否都 ...

  9. Vue基础知识梳理

    1. Vue 实例 1.1 创建一个Vue实例 一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的.可复用的组件树组成.demo 1.2 数据与方法 数据的响应式渲 ...

  10. JZOJ100045 【NOIP2017提高A组模拟7.13】好数

    题目 题目大意 首先有一个定义: 对于一个数,如果和它互质的数可以组成一个等差数列,那么这个数叫"好数". 现在给你一个数列,有三种操作: 1.询问一段区间内的好数的个数. 2.将 ...