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'
我創建了兩個包:一個包包含引導程序和根配置,另一個包含servlet配置。現在,該應用程序的行爲應該像它應該。 – JimHawkins