如何使用spring的autowire为servlet注入Bean

在应用中一般普通的JavaPojo都是由Spring来管理的,所以使用autowire注解来进行注入不会产生问题,但是有两个东西是例外的,一个是 Filter,一个是Servlet,这两样东西都是由Servlet容器来维护管理的,所以如果想和其他的Bean一样使用Autowire来注入的话,是需要做一些额外的功夫的。

对于Filter,Spring提供了DelegatingFilterProxy,所以本文主要讲述Servlet的解决。

1、比较直观但是不大优雅的做法是重写init()方法,在里面使用AutowireCapableBeanFactory来手工告诉Spring:我这个Servlet是需要这样的一个Bean的。具体写法:

public void init(ServletConfig servletConfig) throws ServletException {
     ServletContext servletContext = servletConfig.getServletContext();
     WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
     AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext.getAutowireCapableBeanFactory();
     autowireCapableBeanFactory.configureBean(this, BEAN_NAME);
}

其中,BEAN_NAME就是需要注入的Bean在spring中注册的名字.

这样写的主要问题是就是那个BEAN_NAME,这样写有点主动查找,而不是依赖注入的感觉。

2、创建一个类似于DelegatingFilterProxy那样的代理,通过代理根据配置来找到实际的Servlet,完成业务逻辑功能。

假定我们有一个Servlet名字叫UserServlet,需要注入一个UserManager,伪代码如下:

public class UserServlet extends HttpServlet {
     @Autowired(required = true)
     private UserManager userManager;
}

第一步:

public class DelegatingServletProxy extends GenericServlet {
     private String targetBean;
     private Servlet proxy;
     @Override
     public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
         proxy.service(req, res);
     }
     @Override
     public void init() throws ServletException {
         this.targetBean = getServletName();
         getServletBean();
         proxy.init(getServletConfig());
     }
     private void getServletBean() {
         WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
         this.proxy = (Servlet) wac.getBean(targetBean);
     }
}

第二步:

配置web.xml文件,原来UserServlet的配置大致是这样的:

<servlet>
         <servlet-name>userServlet</servlet-name>
         <servlet-class>com.sample.UserServlet</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>userServlet</servlet-name>
         <url-pattern>/userServlet</url-pattern>
     </servlet-mapping>

现在修改为

<servlet>
         <servlet-name>userServlet</servlet-name>
         <servlet-class>com.sample.DelegatingServletProxy</servlet-class>
     </servlet>
     <servlet-mapping>
         <servlet-name>userServlet</servlet-name>
         <url-pattern>/userServlet</url-pattern>
     </servlet-mapping>

注意,spring是根据Servlet的名字来查找被代理的Servlet的,所以,首先我们要在UserServlet类前面加上 @Component,来告诉Srping:我也是一个Bean。如果名称和Web.xml里面定义的不一样的话,可以在这里指定Bean的名字,比如: @Component("userServlet")

时间: 2024-11-08 18:28:30

如何使用spring的autowire为servlet注入Bean的相关文章

注解失败-Spring整合Mybatis关于Dao注入失败的问题求解

问题描述 Spring整合Mybatis关于Dao注入失败的问题求解 抛出异常 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'adminService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreat

spring学习笔记(4)依赖注入详解

常用的注入方式有四种: 1. 属性注入 2. 构造方法注入 3. 工厂方法注入 4. 注解注入 下面先定义我们后面用到的POJO类: package test; public class User { private String name; private String gender; public String getName() { return name; } public void setName(String name) { this.name = name; } public St

spring中如何获取注入bean里方法上的注解?

问题描述 spring中如何获取注入bean里方法上的注解? 有这样一个需求,在spring中,想用反射获取一个注入bean中方法的注解 一般情况下这样的操作就行了: Method method = bean.getClass().getMethod(...); Annotation[] annotations = method.getAnnotations(); 这样就能获取注解了. 但在spring中,这种方法是获取不到annotation的,原因是这里的bean其实是一个代理类.那么问题来

Spring boot将配置属性注入到bean 专题

@ConfigurationProperties和@value都是将外部属性注入到对象 @ConfigurationProperties很方便使用. 比用@value注解好吗? 在特定的方案中是的,这只是一个选择问题 @EnableConfigurationProperties //开启属性注入,有此注解就可以通过@autowired注入, 是配合@ConfigurationProperties使用的.如果没有@EnableConfigurationProperties,则使用@Configur

spring入门(7) 装配Bean中构造参数的注入

spring装配bean中还有一种Set注入的替代,那就是构造参数的注入. set注入是一种直接方式,缺点是它假设了 所 有的可变属性都可以通过set方法访问到.例如有些属性在创建时设置一次,以后不再改变.替代方式是通过构造函数设 置一些属性值.还有它无法清晰表达哪些属性是必须的,哪些是可选的,构造注入的优势是通过构造强制依赖关系,不可能 实例化不完全的或无法使用的bean.下面是构造器的几种注入方式: 1.通过构造函数注入 (原始方式) 2.根 据构造器参数的类型 3.根据索引index注入

java spring注入bean生成一个类实例,请问这个类实例是单体类吗?全局唯一吗。

问题描述 java spring注入bean生成一个类实例,请问这个类实例是单体类吗?全局唯一吗. 小弟刚从C++转JAVA不久,遇到这样一个问题,求高人帮忙解答. 我现在大体理解了注入的实现方式,例如在一个标注有@configuration 的类里面,如果一个方法 上面有@bean,那么这个方法的返回的类对象会被实例化. 我的疑问是这样的,这个实例化的对象是全局唯一的吗,或者说 是一个单体类吗? 因为我要在我的程序里不同地方使用调用这个bean的方法,我担心如果是单体类的话, 是否存在数据同步

[Spring] 注入Bean属性

通常,JavaBean的属性是私有的,同时拥有一组存取器方法,setXXX()和getXXX()形式存在.Spring可以借助属性的set方法来配置属性的值,以实现setter方式的注入. Kenny是一个很有天赋的乐曲演奏家,由Intrumentalist类定义,如下: package com.springinaction.springidol; public class Instrumentalist implements Performer { public Instrumentalist

struts 2-Struts和Spring整合后访问Action注入失败

问题描述 Struts和Spring整合后访问Action注入失败 如题,刚刚接触SSH,不知道是哪配置出问题了, 蛋疼的是单元测试中用ClassPathXmlApplicationContext读取spring配置文件却通过了- - Struts2配置: <!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 --> <!-- 当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 --&g

Quartz与Spring集成 Job如何自动注入Spring容器托管的对象

  在Spring中使用Quartz有两种方式实现:第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法可以是普通类.很显然,第二种方式远比第一种方式来的灵活.   测试环境 Spring3 M2 quartz-2.1.7 我们要达到这样的效果 public class CancelUnpaidOrderTask implements Job { @Autowired private AppOrderService orderService; @