2015-08-14 87 views
2

我正在編寫一個Tomcat應用程序,該應用程序充當某些內部服務的代理。在根上下文中創建Spring控制器bean並在Servlet上下文中

在遇到一些問題後(請參閱ApplicationContext),我的Tomcat應用程序幾乎按預期運行。

但我的應用程序的日誌記錄說,控​​制器bean被初始化兩次,我沒有找到原因。我不使用XML配置,只使用註釋和Java配置。

在我看來,根上下文中的註釋屬性excludeFilters被忽略。

請參閱下面的課程。 web.xml是空的。

春天引導

package com.application.config; 

import javax.servlet.*; 

import org.springframework.web.WebApplicationInitializer; 
import org.springframework.web.context.ContextLoaderListener; 
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; 
import org.springframework.web.filter.DelegatingFilterProxy; 
import org.springframework.web.servlet.DispatcherServlet; 

public class MyAppSpringBoot implements WebApplicationInitializer 
{ 

    @Override 
    public void onStartup(ServletContext container) throws ServletException 
    { 
     initRootContext(container); 

     initDispatcherContext(container); 

     addFilters(container); 
    } 

    private void initDispatcherContext(ServletContext container) 
    { 
     AnnotationConfigWebApplicationContext servletContext = new AnnotationConfigWebApplicationContext(); 
     servletContext.register(MyAppDispatcherServletContext.class); 
     ServletRegistration.Dynamic dispatcher = 
       container.addServlet("myAppDispatcherServlet", new DispatcherServlet(servletContext)); 
     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/"); 
    } 

    private void initRootContext(ServletContext container) 
    { 
     AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); 
     rootContext.register(MyAppRootContext.class); 
     container.addListener(new ContextLoaderListener(rootContext)); 
    } 

    private void addFilters(ServletContext container) 
    { 
     FilterRegistration.Dynamic registration = 
       container.addFilter("userDbAuthenticationFilter", DelegatingFilterProxy.class); 
     registration.addMappingForUrlPatterns(null, false, "/mapgate/*"); 

     registration = container.addFilter("prepareRequestFilter", DelegatingFilterProxy.class); 
     registration.addMappingForUrlPatterns(null, false, "/mapgate/*"); 

     registration = container.addFilter("responseTextXmlFilter", DelegatingFilterProxy.class); 
     registration.addMappingForUrlPatterns(null, false, "/mapgate/*"); 
    } 
} 

根上下文Java的配置:

package com.application.config; 

import java.io.File; 
import java.io.IOException; 
import java.util.Properties; 
import javax.persistence.EntityManagerFactory; 
import javax.sql.DataSource; 
import javax.xml.stream.*; 

import org.apache.commons.fileupload.disk.DiskFileItemFactory; 
import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.springframework.context.annotation.*; 
import org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException; 
import org.springframework.jdbc.datasource.lookup.JndiDataSourceLookup; 
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 
import org.springframework.stereotype.Controller; 

import com.application.controller.MyAppXmlFilterWords; 
import com.application.urlmapping.UrlPairing; 

@Configuration 
@ComponentScan(basePackages = "com.application", excludeFilters = @ComponentScan.Filter(Controller.class)) 
public class MyAppRootContext 
{ 

    private static Logger logger = LogManager.getLogger(MyAppRootContext.class.getName()); 

    /* 

    These 3 filter beans are annotated with @Component. They are working as expected 

    @Bean 
    public UserDbAuthenticationFilter userDbAuthenticationFilter() 
    { 
     return new UserDbAuthenticationFilter(); 
    } 

    @Bean 
    public PrepareRequestFilter prepareRequestFilter() 
    { 
     return new PrepareRequestFilter(); 
    } 

    @Bean 
    public ResponseTextXmlFilter responseTextXmlFilter() 
    { 
     return new ResponseTextXmlFilter(); 
    } 

    */ 
    @Bean 
    public DataSource userDbJpaDataSource() throws DataSourceLookupFailureException 
    { 

     JndiDataSourceLookup lookup = new JndiDataSourceLookup(); 
     DataSource dataSource = lookup.getDataSource("jdbc/userDbPostgres"); 
     logger.info("U3R Datasource: {}", dataSource); 
     return dataSource; 
    } 

    @Bean 
    public EntityManagerFactory entityManagerFactory() 
    { 
     LocalContainerEntityManagerFactoryBean fb = new LocalContainerEntityManagerFactoryBean(); 
     fb.setDataSource(userDbJpaDataSource()); 
     fb.afterPropertiesSet(); 
     return fb.getNativeEntityManagerFactory(); 
    } 

    @Bean 
    public DiskFileItemFactory diskFileItemFactory() 
    { 
     DiskFileItemFactory factory = new DiskFileItemFactory(); 
     factory.setSizeThreshold(50_000 * 1024); 
     factory.setRepository(new File("/WEB-INF/upload")); 
     return factory; 
    } 

    @Bean 
    public XMLOutputFactory xmlOutputFactory() 
    { 
     return XMLOutputFactory.newInstance(); 
    } 

    @Bean 
    public XMLInputFactory xmlInputFactory() 
    { 
     return XMLInputFactory.newInstance(); 
    } 

    @Bean 
    public XMLEventFactory xmlEventFactory() 
    { 
     return XMLEventFactory.newInstance(); 
    } 

    @Bean 
    public UrlPairing urlPairing() throws IOException 
    { 
     return new UrlPairing(myAppProperties().getProperty("myApp.UrlPairingFile")); 
    } 

    @Bean 
    public Properties myAppProperties() throws IOException 
    { 
     Properties p = new Properties(); 
     p.load(MyAppRootContext.class.getResourceAsStream("/myAppConfig.properties")); 
     return p; 
    } 

    @Bean 
    public MyAppXmlFilterWords xmlFilterWords() throws IOException 
    { 
     MyAppXmlFilterWords words = MyAppXmlFilterWords.createFilterWords(myAppProperties().getProperty("myApp.xmlFilterWordFile")); 
     return words; 
    } 

} 

servlet上下文配置(這裏沒有豆子,都在根上下文)

package com.application.config; 

import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.servlet.config.annotation.EnableWebMvc; 

/** myApplication Spring dispatcher servlet context 
* 
* Created by ulrich.knaack on 11.08.2015. 
*/ 
@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = "com.application.controller", useDefaultFilters = false, includeFilters = @ComponentScan 
     .Filter(Controller.class)) 
public class MyAppDispatcherServletContext 
{ 
// no servlet specific beans required, all in root context 
} 

控制器類

package com.application.controller; 

import java.io.*; 
import java.net.InetAddress; 
import java.net.UnknownHostException; 
import java.util.*; 
import javax.annotation.PostConstruct; 
import javax.servlet.ServletContext; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 

import org.apache.commons.fileupload.FileItem; 
import org.apache.commons.fileupload.FileUploadException; 
import org.apache.commons.fileupload.disk.DiskFileItem; 
import org.apache.commons.fileupload.disk.DiskFileItemFactory; 
import org.apache.commons.fileupload.servlet.ServletFileUpload; 
import org.apache.commons.lang3.StringUtils; 
import org.apache.commons.lang3.exception.ExceptionUtils; 
import org.apache.http.*; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.config.RequestConfig; 
import org.apache.http.client.methods.*; 
import org.apache.http.entity.*; 
import org.apache.http.entity.mime.MultipartEntityBuilder; 
import org.apache.http.impl.client.CloseableHttpClient; 
import org.apache.http.impl.client.HttpClients; 
import org.apache.logging.log4j.LogManager; 
import org.apache.logging.log4j.Logger; 
import org.springframework.beans.BeansException; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.ApplicationContextAware; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 

import com.application.filter.MyAppRequestHelper; 
import com.application.misc.MyAppHttpTools; 

import static com.application.misc.MyAppConstants.*; 

@Controller 
@RequestMapping(value = "mapgate/**") 
public class MyAppProxyController implements ApplicationContextAware 
{ 
    private static final Logger logger = LogManager.getLogger(MyAppProxyController.class.getName()); 

    @Autowired 
    Properties myAppProperties; 

    @Autowired 
    private DiskFileItemFactory diskFileItemFactory; 

    private ApplicationContext appContext; 

    @PostConstruct 
    public void init() throws ServletException 
    { 
     requestLogIntervall = (Integer.parseInt(myAppProperties.getProperty("myApp.requestLogIntervall"))); 
     logger.debug("Controller {} initialisiert. App-Context: {} {}", this.getClass().getName(), 
       appContext.hashCode(), appContext); 

     logger.debug("Beans im Zugriff von Controller:"); 
     for (String beanName : appContext.getBeanDefinitionNames()) 
     { 
      logger.debug("   {}", beanName); 
     } 

     MyAppProxyController controller = (MyAppProxyController) appContext.getBean("myAppProxyController"); 
     logger.debug("controller-hash im Controller={}", controller.hashCode()); 
    } 

    @SuppressWarnings("TryFinallyCanBeTryWithResources") 
    @RequestMapping(method = RequestMethod.POST) 
    protected void doPost(HttpServletRequest customerRequest, 
          HttpServletResponse response) throws ServletException, 
      IOException 
    { 
    // some code 
    } 

    @RequestMapping(method = RequestMethod.GET) 
    protected void doGet(HttpServletRequest customerRequest, HttpServletResponse customerResponse) 
    { 
    // some code 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException 
    { 
     appContext = applicationContext; 
    } 

} 

測井

20150814-165337 INFO [RMI TCP Connection(5)-127.0.0.1] Root WebApplicationContext: initialization started 
20150814-165337 INFO [RMI TCP Connection(5)-127.0.0.1] Refreshing Root WebApplicationContext: startup date [Fri Aug 14 16:53:37 CEST 2015]; root of context hierarchy 
20150814-165337 INFO [RMI TCP Connection(5)-127.0.0.1] Registering annotated classes: [class com.application.config.MyAppRootContext] 
20150814-165337 INFO [RMI TCP Connection(5)-127.0.0.1] URL-Paring Konstruktor, Datei D:/doorman-ent/doorman-conf/urlpairing.txt 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1] URL-Paare aus Datei <D:/doorman-ent/doorman-conf/urlpairing.txt> lesen... 
20150814-165337 INFO [RMI TCP Connection(5)-127.0.0.1] URL-Pairing: es existieren 17 Service-Paar(e) und 2 File-Paar(e) 
20150814-165337 INFO [RMI TCP Connection(5)-127.0.0.1] Filter com.application.filter.PrepareRequestFilter initialisiert. App-Context: 615649080 Root WebApplicationContext: startup date [Fri Aug 14 16:53:37 CEST 2015]; root of context hierarchy 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1] Konstruktor com.application.filter.ResponseTextXmlFilter 
20150814-165337 INFO [RMI TCP Connection(5)-127.0.0.1] Filter com.application.filter.ResponseTextXmlFilter initialisiert. App-Context: 615649080 Root WebApplicationContext: startup date [Fri Aug 14 16:53:37 CEST 2015]; root of context hierarchy 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1] Beans im Zugriff von XMLFilter: 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.annotation.internalConfigurationAnnotationProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.annotation.internalAutowiredAnnotationProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.annotation.internalRequiredAnnotationProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.annotation.internalCommonAnnotationProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.annotation.internalPersistenceAnnotationProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.event.internalEventListenerProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.event.internalEventListenerFactory 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   myAppRootContext 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   myAppDispatcherServletContext 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   prepareRequestFilter 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   responseTextXmlFilter 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   userDbAuthenticationFilter 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   myAppProxyController 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   requestMappingHandlerMapping 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcContentNegotiationManager 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   viewControllerHandlerMapping 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   beanNameHandlerMapping 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   resourceHandlerMapping 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcResourceUrlProvider 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   defaultServletHandlerMapping 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   requestMappingHandlerAdapter 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcConversionService 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcValidator 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcPathMatcher 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcUrlPathHelper 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcUriComponentsContributor 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   httpRequestHandlerAdapter 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   simpleControllerHandlerAdapter 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   handlerExceptionResolver 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   mvcViewResolver 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   diskFileItemFactory 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   entityManagerFactory 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   urlPairing 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   myAppProperties 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   xmlInputFactory 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   userDbJpaDataSource 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   xmlFilterWords 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   xmlOutputFactory 
20150814-165337 DEBUG [RMI TCP Connection(5)-127.0.0.1]   xmlEventFactory 
20150814-165338 DEBUG [RMI TCP Connection(5)-127.0.0.1] Controller com.application.controller.MyAppProxyController initialisiert. App-Context: 615649080 Root WebApplicationContext: startup date [Fri Aug 14 16:53:37 CEST 2015]; root of context hierarchy 
20150814-165338 DEBUG [RMI TCP Connection(5)-127.0.0.1] controller-hash im Controller=1369268001 
20150814-165338 DEBUG [RMI TCP Connection(5)-127.0.0.1] controller-hash im XMLFilter=1369268001 
20150814-165338 INFO [RMI TCP Connection(5)-127.0.0.1] U3R Datasource: [email protected] 
20150814-165338 INFO [RMI TCP Connection(5)-127.0.0.1] Building JPA container EntityManagerFactory for persistence unit 'userDbPersistence' 
20150814-165339 INFO [RMI TCP Connection(5)-127.0.0.1] Filter com.application.filter.UserDbAuthenticationFilter initialisiert. App-Context: 615649080 Root WebApplicationContext: startup date [Fri Aug 14 16:53:37 CEST 2015]; root of context hierarchy 
20150814-165339 DEBUG [RMI TCP Connection(5)-127.0.0.1] EntityManagerFactory: [email protected] 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Mapped "{[/mapgate/**],methods=[GET]}" onto protected void com.application.controller.MyAppProxyController.doGet(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Mapped "{[/mapgate/**],methods=[POST]}" onto protected void com.application.controller.MyAppProxyController.doPost(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Fri Aug 14 16:53:37 CEST 2015]; root of context hierarchy 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Root WebApplicationContext: initialization completed in 2831 ms 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] FrameworkServlet 'myAppDispatcherServlet': initialization started 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Refreshing WebApplicationContext for namespace 'myAppDispatcherServlet-servlet': startup date [Fri Aug 14 16:53:40 CEST 2015]; parent: Root WebApplicationContext 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Registering annotated classes: [class com.application.config.MyAppDispatcherServletContext] 
20150814-165340 DEBUG [RMI TCP Connection(5)-127.0.0.1] Controller com.application.controller.MyAppProxyController initialisiert. App-Context: 332892020 WebApplicationContext for namespace 'myAppDispatcherServlet-servlet': startup date [Fri Aug 14 16:53:40 CEST 2015]; parent: Root WebApplicationContext 
20150814-165340 DEBUG [RMI TCP Connection(5)-127.0.0.1] controller-hash im Controller=1145466717 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Mapped "{[/mapgate/**],methods=[GET]}" onto protected void com.application.controller.MyAppProxyController.doGet(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Mapped "{[/mapgate/**],methods=[POST]}" onto protected void com.application.controller.MyAppProxyController.doPost(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] Looking for @ControllerAdvice: WebApplicationContext for namespace 'myAppDispatcherServlet-servlet': startup date [Fri Aug 14 16:53:40 CEST 2015]; parent: Root WebApplicationContext 
20150814-165340 INFO [RMI TCP Connection(5)-127.0.0.1] FrameworkServlet 'myAppDispatcherServlet': initialization completed in 86 ms 
20150814-165340 WARN [http-apr-8080-exec-4] No mapping found for HTTP request with URI [/doorman/] in DispatcherServlet with name 'myAppDispatcherServlet' 
20150814-165341 WARN [http-apr-8080-exec-10] No mapping found for HTTP request with URI [/doorman/] in DispatcherServlet with name 'myAppDispatcherServlet' 

回答

4

@Configuration@Component一元註釋。換句話說,它也標誌着一個班級成爲組件掃描的候選人。

在你的根配置,你聲明你的組件掃描爲

@ComponentScan(basePackages = "com.application", excludeFilters = @ComponentScan.Filter(Controller.class)) 

MyAppDispatcherServletContext類是在

package com.application.config; 
// [imports] 
@Configuration 
@EnableWebMvc 
@ComponentScan(basePackages = "com.application.controller", useDefaultFilters = false, includeFilters = @ComponentScan 
     .Filter(Controller.class)) 
public class MyAppDispatcherServletContext 

它會因此得到回升,獲取加載和執行自己的配置之內的根上下文(帶有它自己的組件掃描)。

然後它會在servlet上下文中執行相同的操作。

更明確地分開你的包。

+0

我創建了兩個包:一個包包含引導程序和根配置,另一個包含servlet配置。現在,該應用程序的行爲應該像它應該。 – JimHawkins

相關問題