为什么让 spring bean 初始化两次
Why gets the spring bean initialized twice
Spring (mvc) 4.0.3, java 1.7.0_71, tomcat 7.0.57, windows 7
我有一个 Spring MVC 应用程序,有 2 个 applicationContext,applicationContextRoot 加载了:
AbstractAnnotationConfigDispatcherServletInitializer: protected Class<?>[] getRootConfigClasses {
return new Class<?>[] { AppConfig.class }
}
WebApplicationContext 已加载。
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebMvcConfig.class};
}
AppConfig class 包含焦点 Bean 的 bean 定义(Dropwizard 的 MetricRegistry
)
@Configuration
public class AppConfig {
...
@Bean
public MetricRegistry metricRegistry() {
MetricRegistry result = new MetricRegistry();
LOG.info("testing", new Exception("trace me"));
configureReporters(result);
return result;
}
我看到 trace me stacktrace
调用了两次。堆栈跟踪不同:
....zipped
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) [spring-context-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) [spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) [spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4992) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492) [catalina.jar:7.0.57]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.57]
对比(几毫秒后)。
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) [spring-context-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:530) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at javax.servlet.GenericServlet.init(GenericServlet.java:158) [servlet-api.jar:3.0.FR]
> at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1090) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5231) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5518) [catalina.jar:7.0.57]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.57]
bean 第一次是在 web.context.ContextLoader
上下文中创建的,而第二次是在 web.servlet.FrameworkServlet
中创建的
web.xml 除了安全约束之外是空的,初始化是通过 AbstractAnnotationConfigDispatcherServletInitializer
的实例完成的
我不确定这种行为的影响,但它不是我所期望的(bean 是单例等)。如果我取出这个 bean 的每个 @autowired
注释,这种行为仍然存在。我确实检查过只有一个 @componentscan(在 WebMvcConfig 中)
听起来您正在 WebMvcConfig
中扫描组件,但不排除配置 类。
您可以使用:
@ComponentScan(
basePackages = {"mypackage"},
excludeFilters =
@ComponentScan.Filter(
type = FilterType.ANNOTATION,
value = Configuration.class
)
)
Spring (mvc) 4.0.3, java 1.7.0_71, tomcat 7.0.57, windows 7
我有一个 Spring MVC 应用程序,有 2 个 applicationContext,applicationContextRoot 加载了:
AbstractAnnotationConfigDispatcherServletInitializer: protected Class<?>[] getRootConfigClasses {
return new Class<?>[] { AppConfig.class }
}
WebApplicationContext 已加载。
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] {WebMvcConfig.class};
}
AppConfig class 包含焦点 Bean 的 bean 定义(Dropwizard 的 MetricRegistry
)
@Configuration
public class AppConfig {
...
@Bean
public MetricRegistry metricRegistry() {
MetricRegistry result = new MetricRegistry();
LOG.info("testing", new Exception("trace me"));
configureReporters(result);
return result;
}
我看到 trace me stacktrace
调用了两次。堆栈跟踪不同:
....zipped
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) [spring-context-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) [spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) [spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) [spring-web-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4992) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492) [catalina.jar:7.0.57]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.57]
对比(几毫秒后)。
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) [spring-context-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:530) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) [spring-webmvc-4.0.3.RELEASE.jar:4.0.3.RELEASE]
> at javax.servlet.GenericServlet.init(GenericServlet.java:158) [servlet-api.jar:3.0.FR]
> at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1090) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5231) [catalina.jar:7.0.57]
> at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5518) [catalina.jar:7.0.57]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [catalina.jar:7.0.57]
bean 第一次是在 web.context.ContextLoader
上下文中创建的,而第二次是在 web.servlet.FrameworkServlet
中创建的
web.xml 除了安全约束之外是空的,初始化是通过 AbstractAnnotationConfigDispatcherServletInitializer
我不确定这种行为的影响,但它不是我所期望的(bean 是单例等)。如果我取出这个 bean 的每个 @autowired
注释,这种行为仍然存在。我确实检查过只有一个 @componentscan(在 WebMvcConfig 中)
听起来您正在 WebMvcConfig
中扫描组件,但不排除配置 类。
您可以使用:
@ComponentScan(
basePackages = {"mypackage"},
excludeFilters =
@ComponentScan.Filter(
type = FilterType.ANNOTATION,
value = Configuration.class
)
)