@Service 被构造两次 [英] @Service are constructed twice

查看:35
本文介绍了@Service 被构造两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Spring 应用程序有问题,我的 @Service 类在应用程序启动时被创建了两次.我知道这是我的配置问题,因为我以前遇到过,但我到底做错了什么?

I have a problem with my Spring application where my @Service classes are being created twice when the application starts. I know this is a problem with my configuration, as I've experienced it before, but what exactly am I doing wrong?

我在下面布置配置的方式有什么根本性的错误吗?(我把我认为无关的一切都省略了)

Is there anything fundamentally wrong with the way I've laid out my config, below? (I have omitted everything I deem to be irrelevant)

web.xml:

<servlet>
    <servlet-name>myapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/myapp-config.xml
        /WEB-INF/myapp-security.xml
        /WEB-INF/myapp-mvc.xml
    </param-value>
</context-param>

<listener>
    <listener-class>com.myapp.servlet.MyAppContextListener</listener-class>
</listener>

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

myapp-servlet.xml

<context:component-scan base-package="com.myapp" annotation-config="true" />
<mvc:annotation-driven />

myapp-config.xml

<context:component-scan base-package="com.myapp" annotation-config="true" />
<context:annotation-config />

推荐答案

除了 @GaryF 的回答之外,还有针对此问题的以下漂亮解决方案(用于 Spring Roo 生成的项目中):

In addition to @GaryF's answer, there is a following beautiful solution for this problem (used in projects generated by Spring Roo):

<!-- Load everything except @Controllers -->
<context:component-scan base-package="com.myapp">
    <context:exclude-filter expression="org.springframework.stereotype.Controller"
        type="annotation"/>
</context:component-scan>

myapp-servlet.xml

<!-- Load @Controllers only -->
<context:component-scan base-package="com.myapp" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" 
        type="annotation"/>
</context:component-scan>

myapp-config.xml 中删除 意味着,所有自动发现的带注释的 bean 都在 DispatcherServlet 的上下文(即从 myapp-servlet.xml 加载的上下文).

Removing <context:component-scan> from myapp-config.xml means, that all your autodiscovered annotated beans are registered in DispatcherServlet's context (that is, the context loaded from myapp-servlet.xml).

然而,推荐的方法是将 servlet 的上下文用于表示特定的事物(例如控制器),并将根上下文 (myapp-config.xml) 用于应用程序的核心服务.上述解决方案使这种方法变得简单.

However the recommended approach is to use servlet's context for presentation-specific things (such as controllers), and use the root context (myapp-config.xml) for the core services of your application. The solution above make this approach easy.

关于实际考虑,当您的核心服务被放置在 servlet 的应用程序上下文中时,不能从该 servlet 的范围之外访问它们,例如,从另一个 servlet(您可能需要使用另一个 servlet 来实现另一个访问技术)或过滤器(例如 Spring Security 过滤器).这就是在根应用程序上下文中拥有核心服务的原因.

Regarding the practical considerations, when your core services are placed in servlet's application context, they can't be accessed from outside the scope of that servlet, for example, from another servlets (you may need to use another servlets to implement another access technologies) or filters (such as Spring Security filters). That's the reason for having core services in the root application context.

这篇关于@Service 被构造两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆