我想使用Spring在Web应用程序中管理我的JPA DAO,并尝试按照Spring网站示例来了解如何执行此操作。
我正在考虑使用AnnotationConfigWebApplicationContext
代替AnnotationConfigApplicationContext
来引导Spring。
在示例中,它与org.springframework.web.servlet.DispatcherServlet
一起使用,但我想在没有Spring MVC的情况下使用它。
我的web.xml看起来如下:
...
<web-app>
<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.foo.Application</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
</web-app>
我的配置类如下所示:
...
@Configuration
@ComponentScan(basePackages={"com.foo.service"})
public class Application {
@Bean
MessageService mockMessageService() {
return new MessageService() {
@Override
public String getMessages() {
return "Hello Spring World!";
}
};
}
}
是否可以将此示例中的mockMessageService
注入到我的servlet中,还是必须为我的Web应用程序创建一个单独的中央集线器,其中服务是由servlet调用的?
问题是如果我在包com.foo.service
中有我的servlet并尝试使用
@Autowired
获得依赖或尝试一些类似的方法服务不会被注入,我不知道问题出在哪里。有可能这样做吗?或者我应该为AnnotationConfigWebApplicationContext
添加一些工作吗?
答案 0 :(得分:2)
Servlet由servlet容器管理,而不是由spring管理。 Spring不会注入servlet,因为它不会实例化它们。
如果你想在servlet中访问由spring管理的bean,你必须像spring DispatcherServlet
那样进行访问。
E.g。从WebApplicationContext
做
ServletContext
javax.servlet.ServletContext servletContext = ...;
WebApplicationContextUtils.getWebApplicationContext(servletContext);
这是有效的,因为ContextLoaderListener
可确保WebApplicationContext
可用作ServletContext
属性。
由于WebApplicationContext
是ApplicationContext
,您可以自动装配已在弹簧容器外实例化的bean。
例如
ApplicationContext appContext = ...;
AutowireCapableBeanFactory acbf = context.getAutowireCapableBeanFactory();
SomeBean someBean = new SomeBean();
acbf.autowireBean(someBean);
只需将@Autowired
注释放在SomeBean
。
更简单的方法是扩展spring org.springframework.web.servlet.FrameworkServlet
并实现doService
方法。有关详细信息,请阅读FrameworkServket的javadoc。
答案 1 :(得分:2)
如果你有一个servlet,你可以使用类似下面的东西在init方法上连接它:
public class MyServlet implements javax.servlet.Servlet {
@Autowired
MyBean myBean;
@Override
public void init(ServletConfig arg0) throws ServletException {
final AutowireCapableBeanFactory autowireCapableBeanFactory=WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory();
autowireCapableBeanFactory.autowireBean(this);
}
//....
}
如果我有很多servlet,将init方法提取到某个可重用的父类中是很方便的,例如
public class AutowiredServlet implements javax.servlet.Servlet {
@Override
public void init(ServletConfig arg0) throws ServletException {
final AutowireCapableBeanFactory autowireCapableBeanFactory=WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory();
autowireCapableBeanFactory.autowireBean(this);
}
}
并为每个需要自动装配的servlet扩展该类。