Java 如何防止多个bean实例?
我有一个基于Spring的web应用程序,有两个servlet——一个用于MVC,一个用于SpringWS。应用程序中使用了几个bean,它们是使用注释自动连接的。每次应用程序启动时,它都会为每种bean类型创建3个实例,即使它们是单例范围的。@PostConstruct方法也会为每个方法调用三次 我知道有3个应用程序上下文=1个公共+2个servlet,但每个bean、控制器、端点等都创建了三次。至少在父应用程序上下文中加载的公共bean应该只实例化一次 组件扫描的基本包属性指向不相交的包 我使用了一个类来转储上下文信息https://gist.github.com/1347171 似乎有三种不同的上下文具有相同的结构和相同的bean。它们的id是/project/、/project/rest、/project/soap 我尝试注释ContextLoaderListener,删除soap servlet及其关联的XML文件applicationContext&soap servlet,并将常见内容移动到rest servlet中,这样就只有一个配置XML和一个组件扫描,每个bean仍然有3个实例。在这种情况下,应用程序上下文id是/Project/exact-casing、/Project/和/Project/ web.xml applicationContext.xml soap-servlet.xmlJava 如何防止多个bean实例?,java,spring,glassfish,Java,Spring,Glassfish,我有一个基于Spring的web应用程序,有两个servlet——一个用于MVC,一个用于SpringWS。应用程序中使用了几个bean,它们是使用注释自动连接的。每次应用程序启动时,它都会为每种bean类型创建3个实例,即使它们是单例范围的。@PostConstruct方法也会为每个方法调用三次 我知道有3个应用程序上下文=1个公共+2个servlet,但每个bean、控制器、端点等都创建了三次。至少在父应用程序上下文中加载的公共bean应该只实例化一次 组件扫描的基本包属性指向不相交的包 我
在您的bean上使用javax.ejb.Singleton注释。在您的bean上使用javax.ejb.Singleton注释。原因是关于spring mvc上下文初始化的文档有点混乱,这些神奇的注释默认值: 由于以下原因,您可能有三份副本: contextConfigLocation定义创建一个根webapp上下文,每个应用程序只加载一个该上下文,并在所有servlet中共享。每个-servlet-config.xml文件都可以访问这些bean,但反之亦然。 因此,第二个实例来自您的-servlet应用程序上下文,因为您再次明确定义了注释驱动。 不确定您使用的是哪个spring框架版本,但通过定义注释驱动和自定义请求映射适配器,您几乎创建了两个。 事实上,如果你有所有的标签来定制你的适配器,检查你想要的模式。然而,另一种解决方法是在跟踪模式下进行痛苦的调试,并查看到底是哪个bean在创建适配器。在适配器构造函数中放置一个断点,然后查看DispatcherServlet->mapperHandler->interceptor->mapping->context->configFileLocation中的堆栈,查看哪个文件正在创建这个bean 如果要自定义消息转换器,应执行以下操作:
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="afterBurnerObjectMapper"/>
</bean>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
原因是关于SpringMVC上下文初始化的文档有点混乱,还有这些神奇的注释默认值: 由于以下原因,您可能有三份副本: contextConfigLocation定义创建一个根webapp上下文,每个应用程序只加载一个该上下文,并在所有servlet中共享。每个-servlet-config.xml文件都可以访问这些bean,但反之亦然。 因此,第二个实例来自您的-servlet应用程序上下文,因为您再次明确定义了注释驱动。 不确定您使用的是哪个spring框架版本,但通过定义注释驱动和自定义请求映射适配器,您几乎创建了两个。 事实上,如果你有所有的标签来定制你的适配器,检查你想要的模式。然而,另一种解决方法是在跟踪模式下进行痛苦的调试,并查看到底是哪个bean在创建适配器。在适配器构造函数中放置一个断点,然后查看DispatcherServlet->mapperHandler->interceptor->mapping->context->configFileLocation中的堆栈,查看哪个文件正在创建这个bean 如果要自定义消息转换器,应执行以下操作:
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="afterBurnerObjectMapper"/>
</bean>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
你说它们被创造了三次是什么意思?实例化三次?有三个参考资料吗?我在这里使用与您几乎相同的设置,从未注意到任何不规则的活动。你能给我们看一下导致你得出这些结论的任何证据吗?它们被实例化了三次——这可以通过在构造函数中设置断点/跟踪来发现。每个bean的@PostConstruct注释方法也被调用了三次,这意味着实例是“真实的”,而不仅仅是本文所说的一些代理:它们被创建了三次是什么意思?实例化三次?有三个参考资料吗?我在这里使用与您几乎相同的设置,从未注意到任何不规则的活动。你能给我们看一下导致你得出这些结论的任何证据吗?它们被实例化了三次——这可以通过在构造函数中设置断点/跟踪来发现。@PostConstruct anno 每个bean的方法也被调用三次,这意味着实例是“真实的”,而不仅仅是本文所说的一些代理:
<sws:annotation-driven/>
<context:component-scan base-package="test.soap"/>
<sws:dynamic-wsdl
id="service"
portTypeName="service"
locationUri="/soap/service"
targetNamespace="http://server/soap">
<sws:xsd location="/WEB-INF/SoapService.xsd"/>
</sws:dynamic-wsdl>
<sws:interceptors>
<bean id="validatingInterceptor"
class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
<property name="schema" value="/WEB-INF/SoapService.xsd"/>
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="true"/>
</bean>
</sws:interceptors>
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters register-defaults="false">
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper" ref="afterBurnerObjectMapper"/>
</bean>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>