Springboot如何获取上下文ApplicationContext
springboot获取上下文applicationcontext
在项目中遇到了一个场景,就是通过获得上下文然后获取特定的bean。在此遇到了不小的坑,故留下这个篇文章,做个记录。
import org.springframework.beans.beansexception; import org.springframework.beans.factory.annotation.autowired; import org.springframework.context.applicationcontext; import org.springframework.context.applicationcontextaware; import org.springframework.stereotype.component; @component public class springcontextutil implements applicationcontextaware { /** * 上下文对象实例 */ private static applicationcontext applicationcontext; @autowired public void setapplicationcontext(applicationcontext applicationcontext) throws beansexception { this.applicationcontext = applicationcontext; } /** * 获取applicationcontext * @return */ public static applicationcontext getapplicationcontext() { return applicationcontext; } /** * 通过name获取 bean. * @param name * @return */ public static object getbean(string name){ return getapplicationcontext().getbean(name); } /** * 通过class获取bean. * @param clazz * @param <t> * @return */ public static <t> t getbean(class<t> clazz){ return getapplicationcontext().getbean(clazz); } /** * 通过name,以及clazz返回指定的bean * @param name * @param clazz * @param <t> * @return */ public static <t> t getbean(string name,class<t> clazz){ return getapplicationcontext().getbean(name, clazz); } }
看上面的代码,可以看到在工具类中一开始是声明了一个applicationcontext类型的静态变量,但是由于静态变量是不能被spring容器管理的,一开始用正常的getter和setter方法不能获取到特定的bean,实践证明,需要在此变量的setter方法上加上@autowired注解,并且去除setter方法中的static关键字。才可实现特定bean的注入。
springboot的应用上下文
springboot上下文有两个
servletwebserverapplicationcontext
-
annotationconfigservletwebserverapplicationcontext
(继承上面)
servletwebserverapplicationcontext
该类属于spring-boot-2.1.1release.jar中,是自springboot诞生就衍生出来的,是spring框架的应用上下文application的子类。
多说无益,show me code
扩展的功能
首先让我们来看一下,这个类到底做了什么,有什么存在的价值?
private volatile webserver webserver; @override protected void onrefresh() { super.onrefresh(); try { createwebserver(); } catch (throwable ex) { throw new applicationcontextexception("unable to start web server", ex); } }
在此类中有个webserver成员变量,让我们用脚趾头想一下也应该可以知道,这其实就是web服务对象,也基本上可以猜测就是跟tomcat相关了(当然也可以是其他web服务器,如jetty)
然后我们又发现了onrefresh方法,相信我们并不陌生,这就是spring核心refresh方法的中一个钩子方法(即表明此时已经加载所有配置bean),进行webserver对象的创建
@override protected void finishrefresh() { super.finishrefresh(); webserver webserver = startwebserver(); if (webserver != null) { publishevent(new servletwebserverinitializedevent(webserver, this)); } }
我们又发现该类存在finishrefresh,仔细想一下,这个也是spring核心#refresh方法中的一个钩子方法(不过这个特别,因为该方法是refresh方法中的最后一步,即会去实例化spring容器中的所有beandefinition对象)
首先赞一个,这个很巧妙,调用了super.finishrefresh() ,并没有丢弃父类的逻辑功能(这点在多态中,我相信还是会有人犯错,本来是扩展功能,但是直接重写,丢弃了父类的方法,当然spring框架开发大佬肯定不会犯这种错误,对吧!)
第二点重点来了,就是startwebserver,也就是在spring完成实例化之后,就会去启动web服务。
annotationconfigservletwebserverapplicationcontext
小结一下:
首先此类是springboot启动运行run()创建applicationcontext的实现类,不过很可惜,该类并没有很强的实质性扩展。
**唯一作用就是拥有了通过注解加载配置类的作用,即和annotationconfigapplication一样,只不过springboot的运行启动已经是通过注解加载bean类**
(虽然是鸡肋,不过这也符合spring创建类的一贯风格,就是每个类都是高内聚的,即每个类除了父类的功能之外,还都拥有其他扩展的作用。即使创建出来还没有用到就被遗弃,但仍然不能阻止spring开发大佬创建该类,哈哈)
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
推荐阅读
-
Springboot 如何指定获取出 yml文件里面的配置值
-
Springboot如何获取配置文件application.yml中自定义的变量并使用
-
Springboot如何获取上下文ApplicationContext
-
springboot启动时如何获取端口和项目名
-
SpringBoot如何获取application.properties中自定义的值
-
Springboot项目如何获取所有的接口
-
SpringBoot如何实现持久化登录状态获取
-
如何在SpringBoot+Freemarker中获取项目根目录
-
SpringBoot如何获取当前项目全部Controller接口的两种方式
-
SpringBoot如何获取src/main/resource路径下的文件