所以我看到了这个问题:
Spring dependency injection to other instance
想知道我的方法是否可行。
1) 在我的 Spring 应用程序上下文中声明 bean
<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="${jdbc.initialSize}" />
<property name="validationQuery" value="${jdbc.validationQuery}" />
<property name="testOnBorrow" value="${jdbc.testOnBorrow}" />
</bean>
<bean id="apiData" class="com.mydomain.api.data.ApiData">
<property name="dataSource" ref="dataSource" />
<property name="apiLogger" ref="apiLogger" />
</bean>
<bean id="apiLogging" class="com.mydomain.api.data.ApiLogger">
<property name="dataSource" ref="dataSource" />
</bean>
2) 覆盖我的 servlet 的 init 方法,如图所示:
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
this.apiData = (ApiData)ac.getBean("apiData");
this.apiLogger = (ApiLogger)ac.getBean("apiLogger");
}
在 Web 应用程序部署的这一点上,这是否可行,或者 Spring 是否还没有准备好将 bean 交付给我的 servlet?我是否必须做一些更传统的事情,比如将 bean 放入 web.xml
中?
最佳答案
我想利用 Sotirios Delimanolis 提供的解决方案,但在混合中添加了透明的 Autowiring 。 这个想法是将普通的 servlet 转换为可自动连接的对象。
所以我创建了一个父抽象 servlet 类,它检索 Spring 上下文、获取和支持 Autowiring 的工厂,并使用该工厂 Autowiring servlet 实例(实际上是子类)。我还将工厂存储为实例变量,以防子类需要它。
所以父抽象servlet看起来像这样:
public abstract class AbstractServlet extends HttpServlet {
protected AutowireCapableBeanFactory ctx;
@Override
public void init() throws ServletException {
super.init();
ctx = ((ApplicationContext) getServletContext().getAttribute(
"applicationContext")).getAutowireCapableBeanFactory();
//The following line does the magic
ctx.autowireBean(this);
}
}
一个 sevlet 子类看起来像这样:
public class EchoServlet extends AbstractServlet {
@Autowired
private MyService service;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
response.getWriter().println("Hello! "+ service.getMyParam());
}
}
请注意,EchoServlet 唯一需要做的就是在 Spring 的常见实践中声明一个 bean。神奇的是在父类(super class)的 init() 方法中完成的。
我还没有彻底测试过。但它与一个简单的 bean MyService 一起工作,该 bean 还从 Spring 管理的属性文件中获取 Autowiring 的属性。
享受吧!
注意:
最好使用 Spring 自己的上下文监听器加载应用程序上下文,如下所示:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
然后像这样检索它:
WebApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(getServletContext());
ctx = context.getAutowireCapableBeanFactory();
ctx.autowireBean(this);
只需要导入spring-web库,不需要spring-mvc。
关于java - Spring 注入(inject)到 Servlet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18745770/