标准的Spring Web应用程序(由Roo或"Spring MVC Project"模板创建)使用ContextLoaderListener和创建一个web.xml DispatcherServlet.为什么他们不仅使用DispatcherServlet并使其加载完整的配置?
我知道ContextLoaderListener应该用于加载非Web相关的东西,而DispatcherServlet用于加载与Web相关的东西(Controllers,...).这导致两个上下文:父上下文.
背景:
几年来我一直以这种标准方式做这件事.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Handles Spring requests -->
<servlet>
<servlet-name>roo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Run Code Online (Sandbox Code Playgroud)
这通常会导致两个上下文及其之间的依赖关系出现问题.在过去,我始终能够找到解决方案,我强烈认为这使得软件结构/架构总是更好.但现在我面临着两种情境事件的问题.
- 然而这让我重新思考这两个上下文模式,我问自己:为什么我要把自己带入这个麻烦,为什么不用一个加载所有弹簧配置文件DispatcherServlet并ContextLoaderListener完全删除.(我仍然会有不同的配置文件,但只有一个上下文.)
有没有理由不删除ContextLoaderListener?
我正在使用Spring 4.2.0.BUILD-SNAPSHOT事件,由于某些原因我还没想到,监听器在发布任何事件后都会触发两次,无论是从ApplicationEvent延伸还是任何任意事件,但是一切都按预期工作运行测试用例,现在想知道Spring MVC上下文中的注释驱动事件是怎么回事
事件发布界面
public interface ListingRegistrationService {
public void registerListing(ListingResource listing);
}
@Component
class ListingRegistrationServiceImpl implements ListingRegistrationService{
private final ApplicationEventPublisher publisher;
@Autowired
public ListingRegistrationServiceImpl(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
@Override
public void registerListing(ListingResource listing) {
//process
publisher.publishEvent(new ListingCreatedEvent(listing));
System.out.println("Event above...");
}
}
Run Code Online (Sandbox Code Playgroud)
事件监听器
@EventListener
@Async
public void sendMailForSuggestedListing(Supplier<ListingResource> listingCreatedEvent) {
System.out.println("Event fired...");
}
Run Code Online (Sandbox Code Playgroud)
终点/切入点
public ResponseEntity<ResponseStatus> registerListing(@RequestBody @Valid ListingResource listing,BindingResult result) throws URISyntaxException {
ResponseEntity<ResponseStatus> response = null;
listingService.registerListing(listing); // publish the event
response = ResponseEntity.created(new …Run Code Online (Sandbox Code Playgroud)