Spring获取ApplicationContext的几种方法
相关文章链接:
观前提示:
本文所使用的IDEA版本为ultimate 2019.1,JDK版本为1.8.0_141,Tomcat版本为9.0.12。
本文的例子均在上述链接参考文章搭建的框架。
1.ApplicationContext简介
实用的Bean工厂ApplicationContext。
ApplicationContext的中文意思是“应用前后关系”,它继承自BeanFactory接口,除了包含BeanFactory的所有功能之外,在国际化支持、资源访问(如URL和文件)、事件传播等方面进行了良好的支持,被推荐为Java EE应用之首选,可应用在Java APP与Java Web中。
2.获取方法
2.1 通过Spring提供的工具类WebApplicationContextUtils获取
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext);
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext);
ac1.getBean(Class);
ac2.getBean("beanId");
实例
UserService.java
package com.example.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public void insertUser() {
System.out.println("插入用户成功");
}
public boolean updateUser() {
System.out.println("更新用户成功");
return true;
}
}
拦截器RequestMappingInterceptor.java中的部分测试方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext());
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
UserService u1 = ac1.getBean(UserService.class);
UserService u2 = ac2.getBean(UserService.class);
u1.insertUser();
u2.updateUser();
return super.preHandle(request, response, handler);
}
测试结果
注:这种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例。
2.2 初始化时保存ApplicationContext对象
ApplicationContext ac1 = new ClassPathXmlApplicationContext("**/applicationContext.xml");
(Class) ac1.getBean("beanId");
ac1.getBean(Class);
实例
结构如下
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="testApplicationContext"></context:component-scan>
</beans>
TestApplicationContext.java
package testApplicationContext;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApplicationContext{
@Test
public void test() {
try {
ApplicationContext ac1 = new ClassPathXmlApplicationContext("testApplicationContext/applicationContext.xml");
UserService u1 = (UserService) ac1.getBean("userService");
UserService u2 = ac1.getBean(UserService.class);
u1.insertUser();
u2.updateUser();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果如下
注:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring的情况。
2.3 继承自抽象类ApplicationObjectSupport
实例
ApplicationObjectSupportUtil.java
package com.example.util;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Component;
@Component
public class ApplicationObjectSupportUtil extends ApplicationObjectSupport {
private static ApplicationContext applicationContext;
/**
* 重写方法,注入applicationContext
* @param applicationContext
*/
@Override
public void initApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
return (T) applicationContext.getBean(clazz);
}
/**
* 清除applicationContext静态变量.
*/
public static void cleanApplicationContext() {
applicationContext = null;
}
private static void checkApplicationContext() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
}
}
}
拦截器RequestMappingInterceptor.java中的部分测试方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
UserService userService = ApplicationObjectSupportUtil.getBean(UserService.class);
userService.insertUser();
return super.preHandle(request, response, handler);
}
运行结果如下
注:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。
2.4 继承自抽象类WebApplicationObjectSupport
实例
WebApplicationObjectSupportUtils.java
package com.example.util;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.WebApplicationObjectSupport;
@Component
public class WebApplicationObjectSupportUtils extends WebApplicationObjectSupport {
private static ApplicationContext applicationContext;
/**
* 重写方法,注入applicationContext
* @param applicationContext
*/
@Override
public void initApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
return (T) applicationContext.getBean(clazz);
}
/**
* 清除applicationContext静态变量.
*/
public static void cleanApplicationContext() {
applicationContext = null;
}
private static void checkApplicationContext() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
}
}
}
拦截器RequestMappingInterceptor.java中的部分测试方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
UserService userService = WebApplicationObjectSupportUtils.getBean(UserService.class);
userService.insertUser();
return super.preHandle(request, response, handler);
}
运行结果如下
注:类似上面方法,也可以调用getWebApplicationContext()获取WebApplicationContext
2.5 实现接口ApplicationContextAware
实例
SpringContext.java
package com.example.util;
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; // Spring应用上下文环境
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取Spring应用上下文环境
*/
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return applicationContext;
}
/**
* 清除applicationContext静态变量.
*/
public static void cleanApplicationContext() {
applicationContext = null;
}
/**
* 获取对象
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}
/**
* 获取类型为requiredType的对象
*/
public static <T> T getBean(Class<T> clz) {
checkApplicationContext();
return applicationContext.getBean(clz);
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
*/
public static boolean containsBean(String name) {
checkApplicationContext();
return applicationContext.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
*/
public static boolean isSingleton(String name) {
checkApplicationContext();
return applicationContext.isSingleton(name);
}
/**
* Class 注册对象的类型
*/
public static Class<?> getType(String name) {
checkApplicationContext();
return applicationContext.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*/
public static String[] getAliases(String name) {
checkApplicationContext();
return applicationContext.getAliases(name);
}
/**
* 检查applicaitonContext是否注入
*/
private static void checkApplicationContext() {
if (applicationContext == null) {
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
}
}
}
拦截器RequestMappingInterceptor.java中的部分测试方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
UserService userService = SpringContext.getBean(UserService.class);
userService.insertUser();
return super.preHandle(request, response, handler);
}
运行结果如下
注:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。Spring初始化时,会通过该方法将ApplicationContext对象注入。