gpt4 book ai didi

java - 如何防止多个bean实例?

转载 作者:行者123 更新时间:2023-11-29 09:10:29 24 4
gpt4 key购买 nike

我有一个基于 Spring 的 Web 应用程序,它有两个 servlet——一个用于 MVC,一个用于 spring-ws。应用程序中使用了几个 bean,它们是使用注释 Autowiring 的。每次应用程序启动时,它都会为每种 bean 类型创建 3 个实例——即使它们是单例范围的。 @PostConstruct 方法也为每个方法调用了三次。

我理解有3个application context = 1 common + 2 servlets,但是每个bean,controller,endpoint等都创建了3次。至少在父应用程序上下文中加载的公共(public) bean 应该只实例化一次。

component-scan 的 base-package 属性指向不相交的包。

我使用了一个类来转储上下文信息 (https://gist.github.com/1347171),看起来存在三个具有相同结构(相同 bean)的不同上下文。它们的 ID 是“/project/”、“/project/rest”、“/project/soap”。

我尝试注释掉 ContextLoaderListener,删除 soap servlet 及其关联的 XML 文件(applicationContext 和 soap-servlet)并将通用内容移动到其余 servlet 中(这样只有一个配置 xml 和一个组件扫描),我仍然得到每个 bean 的 3 个实例。在这种情况下,应用程序上下文 ID 是“/Project/”(精确大小写)、“/project/”和“/project/”。

web.xml

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>

<servlet>
<servlet-name>soap</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>soap</servlet-name>
<url-pattern>/soap/*</url-pattern>
</servlet-mapping>

applicationContext.xml

<context:annotation-config/>
<context:component-scan base-package="test.common"/>

<task:annotation-driven/>

rest-servlet.xml

<mvc:annotation-driven/>
<context:component-scan base-package="test.rest"/>

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<util:list id="beanList">
<ref bean="formHttpMessageConverter"/>
</util:list>
</property>
</bean>

<bean id="formHttpMessageConverter"
class="org.springframework.http.converter.FormHttpMessageConverter"/>

<mvc:interceptors>
<bean class="test.rest.Interceptor"/>
</mvc:interceptors>

soap-servlet.xml

<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>

最佳答案

在您的 bean 上使用 javax.ejb.Singleton 注释。

关于java - 如何防止多个bean实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12750149/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com