1

For my Spring Application I've used an Aspect solely for the purpose of logging (for logback). Now my next step to achieve web request logging is to invoke this aspect (using pointcut definitions) inside Spring's layer that accepts web requests and sends out web responses a.k.a the ServletDispatcher.

Now, intense Googling has revealed a 100+ voted answer of plugging a custom Servelet Dispatcher here: Spring Boot - How to log all requests and responses with exceptions in single place?

However, when I initialise the following inside my '@Configuration' class:

@Bean(name = DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet() {
    return new LoggableDispatcherServlet();
}

@Bean
public ServletRegistrationBean dispatcherRegistration() {
    return new ServletRegistrationBean(dispatcherServlet());
}

I get the following error:

2017-03-20 19:25:08 ERROR o.s.boot.SpringApplication - Application startup failed 
org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137)
at  ....

Caused by:

org.springframework.boot.context.embedded.EmbeddedServletContainerException: Unable to start embedded Tomcat
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.initialize(TomcatEmbeddedServletContainer.java:117)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.<init>(TomcatEmbeddedServletContainer.java:84)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory.getTomcatEmbeddedServletContainer(TomcatEmbeddedServletContainerFactory.java:537)
    at ... 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dispatcherRegistration' defined in class path resource [com/glass/round/activitystream/core/config/AppConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.servlet.ServletRegistrationBean]: Factory method 'dispatcherRegistration' threw exception; nested exception is java.lang.IllegalStateException: @Bean method AppConfig.dispatcherServlet called as a bean reference for type [org.springframework.web.servlet.DispatcherServlet] but overridden by non-compatible bean instance of type [com.sun.proxy.$Proxy76]. Overriding bean of same name declared in: class path resource [com/glass/round/activitystream/core/config/AppConfig.class]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ...

Caused by: java.lang.IllegalStateException: @Bean method AppConfig.dispatcherServlet called as a bean reference for type [org.springframework.web.servlet.DispatcherServlet] but overridden by non-compatible bean instance of type [com.sun.proxy.$Proxy76]. Overriding bean of same name declared in: class path resource [com/glass/round/activitystream/core/config/AppConfig.class]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:394)
    at com.glass.round.activitystream.core.config.AppConfig$$EnhancerBySpringCGLIB$$ebcc6548.dispatcherServlet(<generated>)
    at com.glass.round.activitystream.core.config.AppConfig.dispatcherRegistration(AppConfig.java:22)
    at com.glass.round.activitystream.core.config.AppConfig$$EnhancerBySpringCGLIB$$ebcc6548.CGLIB$dispatcherRegistration$1(<generated>)
    at com.glass.round.activitystream.core.config.AppConfig$$EnhancerBySpringCGLIB$$ebcc6548$$FastClassBySpringCGLIB$$5f3414d3.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
    at com.glass.round.activitystream.core.config.AppConfig$$EnhancerBySpringCGLIB$$ebcc6548.dispatcherRegistration(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 26 common frames omitted

so the two obvious doubts are: 1.) why is Spring's default DispatcherServlet overriding my explicit Bean definition ? 2.) How to over come the above and will it help me in my goal ? Am I thinking right ?

Community
  • 1
  • 1
arshellium
  • 215
  • 1
  • 6
  • 17

0 Answers0