为了账号安全,请及时绑定邮箱和手机立即绑定

@Service被构造两次

/ 猿问

@Service被构造两次

红颜莎娜 2019-11-15 17:04:17

我的Spring应用程序有一个问题,该应用程序启动时会两次创建我的@Service类。我知道这是我的配置出现的问题,就像我以前经历过的那样,但是我到底在做什么错呢?


我在下面布置配置的方式有什么根本错误吗?(我忽略了我认为无关的所有内容)


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


查看完整描述

3 回答

?
绝地无双

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


myapp-config.xml

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

编辑:


<context:component-scan>从中删除myapp-config.xml意味着,所有自动发现的带注释的Bean都在DispatcherServlet的上下文(即从中加载的上下文myapp-servlet.xml)中注册。


但是,推荐的方法是将servlet的上下文用于特定于表示的内容(例如控制器),并将根上下文(myapp-config.xml)用于应用程序的核心服务。上面的解决方案使这种方法变得容易。


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


查看完整回答
反对 回复 2019-11-15
?
皈依舞

除了@axtavt给出的答案之外,我想在这里给出匹配的Spring JavaConfig。


在RootConfig.java:


@ComponentScan(basePackages = { "com.myapp" },

    excludeFilters = @Filter({Controller.class, Configuration.class}))

在WebMvcConfig.java:


@ComponentScan(basePackages = { "com.myapp" },

    useDefaultFilters = false, includeFilters = @Filter(Controller.class))


查看完整回答
反对 回复 2019-11-15
?
扬帆大鱼

您正在同一基本程序包上进行两次单独的组件扫描。删除其中之一。


查看完整回答
反对 回复 2019-11-15
  • 3 回答
  • 0 关注
  • 54 浏览
我要回答

相关问题推荐

慕课专栏
更多

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信