tha*_*guy 23 java spring servlets dependency-injection
所以我看到了这个问题:
并想知道我的方法是否会成功.
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>
Run Code Online (Sandbox Code Playgroud)
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");
}
Run Code Online (Sandbox Code Playgroud)
这个工作还是Spring还没准备好在Web应用程序部署中将bean交付给我的servlet?我是否必须做一些更传统的事情,比如把豆子放进去web.xml?
Agu*_*hez 39
我想利用Sotirios Delimanolis提供的解决方案,但为混合添加透明自动装配.我们的想法是将普通的servlet转换为支持autowire的对象.
所以我创建了一个父抽象servlet类,它检索Spring上下文,获取和支持自动装配的工厂,并使用该工厂自动装配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);
}
}
Run Code Online (Sandbox Code Playgroud)
一个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());
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,EchoServlet唯一需要做的就是在常见的Spring实践中声明一个bean.魔术是在超类的init()方法中完成的.
我还没有彻底测试过它.但是它使用了一个简单的bean MyService,它还从Spring管理的属性文件中获取了一个自动装配的属性.
请享用!
注意:
最好用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>
Run Code Online (Sandbox Code Playgroud)
然后像这样检索它:
WebApplicationContext context = WebApplicationContextUtils
.getWebApplicationContext(getServletContext());
ctx = context.getAutowireCapableBeanFactory();
ctx.autowireBean(this);
Run Code Online (Sandbox Code Playgroud)
只需要导入spring-web库,而不是spring-mvc.
Sot*_*lis 28
你要做的就是让每个人Servlet都拥有自己的ApplicationContext实例.也许这就是你想要的,但我对此表示怀疑.一个ApplicationContext应该是唯一的应用程序.
这样做的恰当方法是设置你ApplicationContext的ServletContextListener.
public class SpringApplicationContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
sce.getServletContext().setAttribute("applicationContext", ac);
}
... // contextDestroyed
}
Run Code Online (Sandbox Code Playgroud)
现在,所有servlet都可以ApplicationContext通过ServletContext属性访问相同的内容.
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
ApplicationContext ac = (ApplicationContext) config.getServletContext().getAttribute("applicationContext");
this.apiData = (ApiData)ac.getBean("apiData");
this.apiLogger = (ApiLogger)ac.getBean("apiLogger");
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这里的答案只对我有用.特别是带有@Configuration注释的类被忽略了,我不想使用xml配置文件.以下是我使用基于Spring(4.3.1)注释的设置进行注射工作的方法:
在web-app下的web.xml中引导AnnotationConfigWebApplicationContext.作为参数,您需要contextClass和contextConfigLocation(您的带注释的配置类):
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.example.config.AppConfig</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
然后覆盖servlet中的init方法.我使用了一个扩展HttpServlet的抽象类,所以我不必在每个servlet中重复它:
@Configurable
public abstract class MySpringEnabledServlet extends HttpServlet
{
@Override
public void init(
ServletConfig config) throws ServletException
{
super.init(config);
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
}
[...]
}
Run Code Online (Sandbox Code Playgroud)
最后我在web.xml中提到的AppConfig类中有我的主配置:
@Configuration
@ComponentScan(basePackages = "com.example")
@Import(
{ SomeOtherConfig.class })
public class AppConfig
{
}
Run Code Online (Sandbox Code Playgroud)
dependend类注释:
@Component
public class AnnotatedClassToInject
Run Code Online (Sandbox Code Playgroud)
并通过我的servlet中的自动装配注入:
@Autowired
private AnnotatedClassToInject myClass;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34121 次 |
| 最近记录: |