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

查看:91
本文介绍了@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中删除<context:component-scan>意味着,所有自动发现的带注释的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来实现另一个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天全站免登陆