在Spring容器外调用bean
这个东西源于这种需求:一个应用丢到服务其后,不管用户有没有访问项目,这个后台线程都必须给我跑,而且这个线程还调用了Spring注入的bean,这样自然就会想到去监听Servlet的状态,当Servlet初始化完毕后会调用ServletContextListener中的contextInitialized方法,所以可以创建一个监听器继承ServletContextListener类来监听Servlet的状态,在contextInitialized方法中来启动后台的线程,但是如何使用Spring注入的bean呢?所以必须确保在启动线程前Spring容器必须初始化完毕,Spring的初始化也是有Listener完成的,所以这里特别注意的是自定的监听器必须放在Spring的监听器之后(很重要),否则无法获取bean属性,会报空指针异常!
1.创建监听器
package com.hhu.listener; import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.hhu.threads.DiagnosisThread; /**
* 这个监听器在WEB容器初始化后就立刻启用了
* @author Weiguo Liu
* @data 2017年11月30日
*/ public class ContextListener implements ServletContextListener { @Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("加载应用程序...");
// StationService stationService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(StationService.class);
// System.out.println("stationService=" + stationService); /*
* 创建诊断线程并启动
*/
DiagnosisThread dt = new DiagnosisThread();
dt.start();
System.out.println("Listener继续执行");
} @Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub } }
2.web.xml配置启动顺序
<!-- 这里不能少,web启动后会按这个位置寻找Spring的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/spring-*.xml
</param-value>
</context-param> <listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <listener>
<listener-class>
com.hhu.listener.ContextListener
</listener-class>
</listener> <servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
3.写一个获取Spring Bean的工具类
由于ServletContextListener并不被Spring管理,所以我们不能使用@Autowired注解来获取相应的bean属性,而是利用ApplicationContext来获取Bean,代码如下
package com.hhu.util; import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; /**
* 使用getBean可以获取对应的bean,自己的的手动进行类型强转
* 创建获取SpringBean的工具类
* @author Weiguo Liu
*
*/
public class SpringBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBeanUtil.applicationContext = applicationContext;
} public static Object getBeanByName(String beanName) {
if (applicationContext == null) {
return null;
}
return applicationContext.getBean(beanName);
} public static <T> T getBean(Class<T> type) {
return applicationContext.getBean(type);
}
}
这样以后就可以在后台线程中愉快的获取Spring bean了,这个工具类很强大,只要Spring初始化后,不管所在类是否被Spring管理,都可以使用如下的方式获取
bean的类型 bean的名字 = (bean的类型)SpringBeanUtil.getBeanByName("bean的名字");
做的越多,也就发现自己不懂的越多,还是要深入理解其原理啊
在Spring容器外调用bean的更多相关文章
- Spring—容器外的Bean使用依赖注入
认识AutowireCapableBeanFactory AutowireCapableBeanFactory是在BeanFactory的基础上实现对已存在实例的管理.可以使用这个接口集成其他框架,捆 ...
- 如何在自定义Listener(监听器)中使用Spring容器管理的bean
正好以前项目中碰到这个问题,现在网上偶然又看到这个问题的博文,那就转一下吧. 原文:http://blog.lifw.org/post/46428852 感谢作者 另外补充下:在web Server容 ...
- 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean
7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...
- 7 -- Spring的基本用法 -- 5... Spring容器中的Bean;容器中Bean的作用域;配置依赖;
7.5 Spring容器中的Bean 7.5.1 Bean的基本定义和Bean别名 <beans.../>元素是Spring配置文件的根元素,该元素可以指定如下属性: default-la ...
- SpringBoot 之 普通类获取Spring容器中的bean
[十]SpringBoot 之 普通类获取Spring容器中的bean 我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器 ...
- 【String注解驱动开发】面试官让我说说:如何使用FactoryBean向Spring容器中注册bean?
写在前面 在前面的文章中,我们知道可以通过多种方式向Spring容器中注册bean.可以使用@Configuration结合@Bean向Spring容器中注册bean:可以按照条件向Spring容器中 ...
- 从Spring容器中获取Bean。ApplicationContextAware
引言:我们从几个方面有逻辑的讲述如何从Spring容器中获取Bean.(新手勿喷) 1.我们的目的是什么? 2.方法是什么(可变的细节)? 3.方法的原理是什么(不变的本质)? 1.我们的目的是什么? ...
- 在listener或者工具中使用spring容器中的bean实例
在项目中经常遇见需要在Listener中或者工具中使用Spring容器中的bean实例,由于bean不能在stataic的类中使用. 介绍一种方式: public class SpringTool { ...
- 获取Spring容器中的Bean协助调试
在使用Spring进行开发时,有时调bug真的是很伤脑筋的一件事,我们可以通过自定义一个监听器来获取Spring容器中的Bean实例来协助我们调试. 第一步:编写自定义监听器 /** * 监听serv ...
随机推荐
- dpkg -i libequinox-osgi-java_3.8.1-8_all.deb
dpkg -i libequinox-osgi-java_3.8.1-8_all.deb dpkg -i libequinox-osgi-java_3.8.1-8_all.deb https://ww ...
- Java 和JavaScript实现C#中的String.format效果
1.Java实现 /** * 需要引入com.alibaba.fastjson.1.2.8 * String result2=HuaatUtil.format(templa ...
- 使用gson将字符串转换成对象
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create(); System.out.pr ...
- 利用pipework为docker容器设置固定IP
今天介绍如何在redhat/centos7系列机器上使用pipework为docker启动的容器指定一个固定ip,我们知道默认情况下,docker会使用 bridge网络模式为每一个启动的容器动态分配 ...
- 【BZOJ3196】【Luogu P3380】 【模板】二逼平衡树(树套树)
做数据结构一定要平\((fo)\)心\((de)\)静\((yi)\)气\((pi)\)...不然会四处出锅的\(QAQ\) 写法:线段树套平衡树,\(O(Nlog^3N)\).五个操作如果是对于整个 ...
- Django框架简介(1)
目录 手写web框架 基于wsgiref模块写web服务端框架 python三大主流框架 django框架介绍 注意事项 django下载方法 django项目及app的创建 命令行创建项目 pych ...
- 29.连续子数组的最大和(python)
题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量 ...
- head first 设计模式笔记5-单例模式
目录: 1.单例模式(Singleton Pattern) 2.概念 3.饿汉式:不是延迟加载,加载类的时候直接初始化 4.懒汉式:延迟加载,首次需要使用的时候在实例化,需要考虑线程安全 5.静态内部 ...
- jQuery_attr()操作
下面来介绍jQuery的属性attr()操作: <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...
- UMG里没有"Prefab"怎么办?
大家知道在Unity里做UI,利用Prefab是少不了的,但是在UE4里如何做呢? 这是实际工作中遇到的问题,我Google关键词“UMG Prefab","UMG resuabl ...