我有一个Spring测试配置类,应该重写xml-config中bean中的现有类。但是我的问题是xml bean覆盖了我的test-config中用primary注释的bean。我尝试用其他名称命名测试豆,但这对我也不起作用。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {CamelJmsTest.TestConfig.class})
public class CamelJmsTest {
@Configuration
@ImportResource("classpath:production-beans-camel-jms.xml")
public static class TestConfig {
@Primary
@Bean
public JmsTemplate jmsTemplate() {
return new JmsTemplate(new ActiveMQConnectionFactory("", "", ACTIVE_MQ_HOST));
}
@Primary
@Bean // ideally i just want this bean to override the bean imported from the xml config
public RouteConfigBuilder routeConfig() {
return RouteConfigBuilder.builder().autoStart(true).build();
}
@Primary
@Bean
public RouteBuilder routeBuilder(@Value("${amq.endpoint}") String endpoint,
@Autowired Processor processor) {
return new RouteBuilder(routeConfig(), "", endpoint, processor);
}
}
private static final String ACTIVE_MQ_HOST = "vm://activeMQ";
@BeforeClass
public static void setActiveMQ() {
System.setProperty("amq.endpoint", ACTIVE_MQ_HOST);
}
@Autowired
JmsTemplate jmsTemplate;
@Test
public void postJmsMessage() {
jmsTemplate.send("queue/test", new MessageCreator() {
@Override
public Message createMessage(Session session) throws
JMSException {
return session.createTextMessage("Hello World");
}
});
try {
for (int i = 0; i < 100; i++) {
Thread.sleep(100);
}
} catch (Exception ignored) {
}
}
}
这是相关的xml配置:
<bean id="routeConfig" class="routing.RouteConfigBuilder" init-method="builder">
<constructor-arg name="redeliveryDelay" value="${<props>.redeliveryDelay}" />
<constructor-arg name="maximumRedeliveries" value="${<props>.maximumRedeliveries}" />
<constructor-arg name="autoStart" value="false" />
</bean>
<bean id="routeBuilder" class="routing.RouteBuilder">
<constructor-arg ref="routeConfig" />
<constructor-arg name="routeId" value="ROUTE_ID_1"/>
<constructor-arg name="endpoint" value="${amq.endpoint}" />
<constructor-arg name="processor" ref="myProcessor" />
</bean>
这是日志输出。运行测试时:
Overriding bean definition for bean 'routeConfig' with a different
definition:
replacing [Root bean: class [null]; scope=; abstract=false;
lazyInit=false; autowireMode=3; dependencyCheck=0;
autowireCandidate=true; primary=true;
factoryBeanName=CamelJmsTest.TestConfig;
factoryMethodName=routeConfig; initMethodName=null;
destroyMethodName=(inferred);
defined in CamelJmsTest]
with [Generic bean: class [RouteConfigBuilder]; scope=;
abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0;
autowireCandidate=true; primary=false; factoryBeanName=null;
factoryMethodName=null; initMethodName=builder;
destroyMethodName=null;
defined in class path resource [production-beans-camel-jms.xml.xml]]
您可以看到我的测试配置中的主要bean被覆盖,我想在测试中使用我的test-config bean。
我正在使用Spring 4.3.x。
我已经阅读了很多相关的文章,但是没有一个给我答案。任何帮助,将不胜感激。
答案 0 :(得分:4)
名称更改似乎适用于我的简化版本。
我认为这并不重要,但是Java和XML之间的RouteConfigBuilder和RouteBuilder的构造样式似乎有所不同。
经过4.3.20测试
package com.stackoverflow.q53757986;
import static org.junit.Assert.*;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Primary;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;
@SuppressWarnings("javadoc")
public class CamelJmsTest {
static final String ACTIVE_MQ_HOST = "vm://activeMQ?broker.persistent=false";
/** The Constant SPRING_CLASS_RULE. */
@ClassRule
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
/** The spring method rule. */
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@BeforeClass
public static void setActiveMQ() {
System.setProperty("amq.endpoint", ACTIVE_MQ_HOST);
}
@Autowired
JmsTemplate jmsTemplate;
@Autowired
RouteConfigBuilder routeConfig;
@Autowired
RouteBuilder routeBuilder;
@Test
public void postJmsMessage() {
assertEquals("java", this.routeConfig.source);
assertEquals("java", this.routeBuilder.source);
this.jmsTemplate.send("queue/test", (MessageCreator) session -> session.createTextMessage("Hello World"));
try {
for (int i = 0; i < 100; i++) {
Thread.sleep(100);
}
} catch (Exception ignored) {}
}
@Configuration
@ImportResource("classpath:production-beans-camel-jms.xml")
static class TestConfig {
@Primary
@Bean
public JmsTemplate jmsTemplate() {
return new JmsTemplate(new ActiveMQConnectionFactory("", "", ACTIVE_MQ_HOST));
}
@Primary
@Bean // ideally i just want this bean to override the bean imported from the xml config
public RouteConfigBuilder routeConfig2() {
return new RouteConfigBuilder("java");
}
@Primary
@Bean
public RouteBuilder routeBuilder2() {
return new RouteBuilder(routeConfig2(), "java");
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
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.xsd">
<bean id="routeConfig" class="com.stackoverflow.q53757986.RouteConfigBuilder">
<constructor-arg name="source" value="xml" />
</bean>
<bean id="routeBuilder" class="com.stackoverflow.q53757986.RouteBuilder">
<constructor-arg name="routeConfig" ref="routeConfig" />
<constructor-arg name="source" value="xml" />
</bean>
</beans>