Spring 尝试 @Autowire 我的依赖项两次
Spring attempting to @Autowire my dependencies twice
我有一个 Spring MVC 应用程序,我在其中尝试在使用 @Controller 注释的 class 中使用 @Autowired。在没有 @Controller 注释的 classes 中,@Autowired 工作正常,一旦我添加 @Controller 注释,我在启动时得到一个巨大的堆栈跟踪,主要归结为 No qualifying bean of type [com.fasterxml.jackson.databind.ObjectMapper] found for dependency
我感觉到 Spring 正在尝试自动装配我的依赖项两次?
我将在我的问题中进一步证明......
在我的 web.xml
中,我正在加载我的 contextConfigLocation 和 DispatcherServlet:
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext.xml</param-value>
</context-param>
....
<servlet>
<servlet-name>ahpw-api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ahpw-api</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
....
webmvc-config.xml 仅包含允许我打开 Jackson JSON API:
的基本知识
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="com.ahpw.api" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<!-- Cookies Filter to set cookies on JSON AJAX responses -->
<mvc:interceptors>
<bean id="cookieInterceptor" class="com.ahpw.api.controller.COOKIEFilter"/>
</mvc:interceptors>
</beans>
在我的 applicationContext.xml 我有以下内容:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
<context:spring-configured/>
<context:component-scan base-package="com.ahpw.api" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Service" type="annotation"/>
</context:component-scan>
<!-- Setup Jackson instance -->
<bean id="jackson" class="com.fasterxml.jackson.databind.ObjectMapper" />
<!-- Setup RabbitMQ -->
<bean id="nativeConnectionFactory" class="com.rabbitmq.client.ConnectionFactory">
<property name="connectionTimeout" value="${rabbit.connection.timeout}"/>
<property name="requestedHeartbeat" value="${rabbit.heartbeat}"/>
</bean>
<rabbit:connection-factory
id="connectionFactory"
port="${rabbit.port}"
virtual-host="${rabbit.virtual}"
host="${rabbit.host}"
username="${rabbit.username}"
password="${rabbit.password}"
connection-factory="nativeConnectionFactory"/>
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" reply-timeout="${rabbit.rpc.timeout}" />
</beans>
我的class发生冲突的地方是这样开始的:
@Service
@Controller
@RequestMapping("/auth")
@JsonIgnoreProperties(ignoreUnknown = true)
public class AuthenticationController extends AbstractRPCPublisher<AuthenticationRequest, AuthenticationResponse> {
@Autowired
AmqpTemplate template;
@Autowired
ObjectMapper mapper;
如果我删除@Controller,一切都会正常启动,但显然 /auth
的请求映射停止工作。
如果我放回@Controller 并在 webmvc-config.xml
中复制 jackson bean 和 rabbitMQ 好东西,它启动时没有错误,但这意味着每个资源都有两个实例,两个 WEB 中的配置副本-INF 和 META-INF,不可取。
有没有办法通过 webmvc-config.xml
实例化我的控制器,但告诉它忽略 @Autowired 以便我的 applicationContext 可以处理它们,如果是这样,@Autowire 会正常运行吗?
您必须定义 ContextLoaderListener
侦听器,它将创建您的 Web 应用程序的根上下文并加载 <context-param>
标签中的 contextConfigLocation
定义:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
因此 applicationContext.xml
应用程序上下文中定义的 bean 将可用于 webmvc-config.xml
应用程序上下文。
不知道是不是打错了,但是AuthenticationController
class一定不要注解@Service
,@Controller
就够了
我有一个 Spring MVC 应用程序,我在其中尝试在使用 @Controller 注释的 class 中使用 @Autowired。在没有 @Controller 注释的 classes 中,@Autowired 工作正常,一旦我添加 @Controller 注释,我在启动时得到一个巨大的堆栈跟踪,主要归结为 No qualifying bean of type [com.fasterxml.jackson.databind.ObjectMapper] found for dependency
我感觉到 Spring 正在尝试自动装配我的依赖项两次? 我将在我的问题中进一步证明......
在我的 web.xml
中,我正在加载我的 contextConfigLocation 和 DispatcherServlet:
....
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext.xml</param-value>
</context-param>
....
<servlet>
<servlet-name>ahpw-api</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ahpw-api</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
....
webmvc-config.xml 仅包含允许我打开 Jackson JSON API:
的基本知识<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<context:component-scan base-package="com.ahpw.api" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<!-- Cookies Filter to set cookies on JSON AJAX responses -->
<mvc:interceptors>
<bean id="cookieInterceptor" class="com.ahpw.api.controller.COOKIEFilter"/>
</mvc:interceptors>
</beans>
在我的 applicationContext.xml 我有以下内容:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
<context:spring-configured/>
<context:component-scan base-package="com.ahpw.api" use-default-filters="false">
<context:include-filter expression="org.springframework.stereotype.Service" type="annotation"/>
</context:component-scan>
<!-- Setup Jackson instance -->
<bean id="jackson" class="com.fasterxml.jackson.databind.ObjectMapper" />
<!-- Setup RabbitMQ -->
<bean id="nativeConnectionFactory" class="com.rabbitmq.client.ConnectionFactory">
<property name="connectionTimeout" value="${rabbit.connection.timeout}"/>
<property name="requestedHeartbeat" value="${rabbit.heartbeat}"/>
</bean>
<rabbit:connection-factory
id="connectionFactory"
port="${rabbit.port}"
virtual-host="${rabbit.virtual}"
host="${rabbit.host}"
username="${rabbit.username}"
password="${rabbit.password}"
connection-factory="nativeConnectionFactory"/>
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" reply-timeout="${rabbit.rpc.timeout}" />
</beans>
我的class发生冲突的地方是这样开始的:
@Service
@Controller
@RequestMapping("/auth")
@JsonIgnoreProperties(ignoreUnknown = true)
public class AuthenticationController extends AbstractRPCPublisher<AuthenticationRequest, AuthenticationResponse> {
@Autowired
AmqpTemplate template;
@Autowired
ObjectMapper mapper;
如果我删除@Controller,一切都会正常启动,但显然 /auth
的请求映射停止工作。
如果我放回@Controller 并在 webmvc-config.xml
中复制 jackson bean 和 rabbitMQ 好东西,它启动时没有错误,但这意味着每个资源都有两个实例,两个 WEB 中的配置副本-INF 和 META-INF,不可取。
有没有办法通过 webmvc-config.xml
实例化我的控制器,但告诉它忽略 @Autowired 以便我的 applicationContext 可以处理它们,如果是这样,@Autowire 会正常运行吗?
您必须定义 ContextLoaderListener
侦听器,它将创建您的 Web 应用程序的根上下文并加载 <context-param>
标签中的 contextConfigLocation
定义:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
因此 applicationContext.xml
应用程序上下文中定义的 bean 将可用于 webmvc-config.xml
应用程序上下文。
不知道是不是打错了,但是AuthenticationController
class一定不要注解@Service
,@Controller
就够了