【转】WebApplicationContextUtils

本文介绍了如何在Web环境中通过Spring的工具类WebApplicationContextUtils获取WebApplicationContext对象,包括两种主要的方法:getWebApplicationContext()和getRequiredWebApplicationContext(),并提供了一个具体的Servlet示例。

当 web 应用集成 Spring 容器后,代表 Spring 容器的WebApplicationContext对象将以

WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 为键存放在ServletContext的属性列表中。您当然可以直接通过以下语句获取 WebApplicationContext:

WebApplicationContext wac = (WebApplicationContext)servletContext.

getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);


但通过位于 org.springframework.web.context.support 包中的WebApplicationContextUtils 工具类获取 WebApplicationContext 更方便:

WebApplicationContext wac =WebApplicationContextUtils.

getWebApplicationContext(servletContext);

当 ServletContext 属性列表中不存在 WebApplicationContext 时,getWebApplicationContext() 方法不会抛出异常,它简单地返回 null。如果后续代码直接访问返回的结果将引发一个 NullPointerException 异常,而 WebApplicationContextUtils 另一个 getRequiredWebApplicationContext(ServletContext sc) 方法要求 ServletContext 属性列表中一定要包含一个有效的 WebApplicationContext 对象,否则马上抛出一个 IllegalStateException 异常。我们推荐使用后者,因为它能提前发现错误的时间,强制开发者搭建好必备的基础设施。

实例:
public class demoServlet extends HttpServlet {
 IDemoWS demoWS;
 public void init() throws ServletException {          
        super.init();
        ServletContext servletContext = this.getServletContext();  
        WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        demoWS = (ISignpicWS)ctx.getBean("demoWS");
    }   
 protected void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {
  .....//request.getSession().getServletContext()
 }
}

 

使用spring的工具类获得容器中的bean对象 

public static IMail getMail(HttpServletRequest request)throws Exception{
  ServletContext sc = request.getSession().getServletContext();
  ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
  IMail mail = (IMail) ac.getBean("emailImpl");
  return mail;
 }

### 关于Spring框架中ApplicationContextWebApplicationContextUtils的新用法或替代写法 在现代Spring应用开发中,`ApplicationContext` 和 `WebApplicationContextUtils` 是两个非常重要的工具类。随着Spring框架的发展,许多传统方式已经被更简洁、现代化的方式所取代。 #### 1. **使用 `@Autowired` 注解简化依赖注入** 传统的手动获取 `ApplicationContext` 的方式可以通过依赖注入机制来优化。例如,在Spring管理的Bean中可以直接通过 `@Autowired` 注解完成对 `ApplicationContext` 的注入[^5]: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; public class MyService { @Autowired private ApplicationContext applicationContext; public void doSomething() { System.out.println(applicationContext); } } ``` 这种方式不仅减少了代码量,还提高了可读性和维护性。 --- #### 2. **利用 `GenericApplicationContext` 或 `AnnotationConfigApplicationContext`** 对于非Web环境下的Spring应用程序,可以考虑使用 `GenericApplicationContext` 或者基于Java配置的 `AnnotationConfigApplicationContext` 来代替传统的XML配置方式[^6]。这种做法更加灵活且易于测试: ```java import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class MainApp { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); MyService myService = context.getBean(MyService.class); myService.doSomething(); context.close(); } } @Configuration class AppConfig { @Bean public MyService myService() { return new MyService(); } } ``` 这种方法特别适合微服务架构中的模块化设计需求。 --- #### 3. **借助 `WebApplicationContextUtils` 获取上下文实例** 尽管 `WebApplicationContextUtils` 已经存在多年,但它仍然是从Servlet环境中快速获取 `WebApplicationContext` 的有效手段之一。然而,为了适应新的编程范式,推荐将其与Spring Boot结合使用,从而减少显式的调用次数[^7]: ```java import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; public class CustomFilter implements Filter { private WebApplicationContext wac; @Override public void init(FilterConfig filterConfig) throws ServletException { this.wac = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext()); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // Use the WebApplicationContext instance here... } } ``` 虽然此方法仍然可用,但在Spring Boot项目中通常不需要直接操作此类工具类,因为所有的组件都已自动注册到IoC容器中。 --- #### 4. **采用Spring Boot自动化配置** 如果正在构建的是一个Spring Boot项目,则无需担心如何初始化或者访问 `ApplicationContext` 。只需启用默认扫描路径即可让所有必要的bean被正确加载[^8]: ```properties # application.properties spring.main.allow-bean-definition-overriding=true ``` 此外,还可以定义自己的事件监听器以响应特定的应用生命周期阶段变化: ```java @Component public class AppStartupRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { System.out.println("Application started successfully!"); } } ``` 这表明了Spring生态系统的不断进化使得开发者能够专注于业务逻辑而非底层细节处理。 --- #### 5. **静态持有单例模式改进版** 当确实需要跨线程共享同一个 `ApplicationContext` 实例时,可通过如下所示的设计模式实现安全高效的重用策略[^9]: ```java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public final class SpringContextHolder { private static ApplicationContext applicationContext; private SpringContextHolder() {} public static synchronized void setApplicationContext(ApplicationContext ctx) { if (ctx != null && applicationContext == null) { applicationContext = ctx; } else { throw new IllegalStateException("ApplicationContext already initialized."); } } public static ApplicationContext getApplicationContext() { assertContextInjected(); return applicationContext; } private static void assertContextInjected() { if (applicationContext == null) { throw new IllegalStateException("ApplicationContext not injected yet."); } } } ``` 随后可以在任何地方轻松获得当前运行期内的唯一上下文引用而不用担心重复创建带来的性能损耗问题。 --- ### 总结 综上所述,无论是通过注解驱动型开发还是完全抛弃XML投纯编码风格怀抱,亦或是充分利用Spring Boot强大的开箱即用特性,都能找到适合自己团队技术栈的最佳实践方案。当然也要记得遵循官方文档指导以及社区最佳实践经验来进行实际项目的落地实施工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值