当前位置: 首页 > 知识库问答 >
问题:

配置中由ImportResource覆盖的主spring bean

越涵衍
2023-03-14
@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) {
    }
  }
}
<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]]

我使用的是Spring4.3.x。

我看过很多相关的帖子,但没有一篇给我答案。如有任何帮助,我们将不胜感激。

共有1个答案

冯元魁
2023-03-14

名字的改变似乎对我的简化版起作用。

我认为这并不重要,但RouteConfigBuilder和RouteBuilder的构造风格在Java和XML之间似乎有所不同。

用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>   
 类似资料:
  • 尝试使用java kafka adminClient配置新创建的kafka主题时,会覆盖值。 我曾尝试使用控制台命令设置相同的主题配置,但效果很好。不幸的是,当我尝试通过Java代码时,一些值发生冲突并被覆盖。 我希望该主题正确地包含所有给定的配置值。

  • 然后我们有这样的服务: 我的第一个bean是由@repository注释创建的,另一个bean是在Spring配置类中声明的: 如果我运行我的应用程序,SomeServiceImpl中的属性someDaoAnotherDataSource没有在配置类中声明我的bean,而是用注释存储库声明了bean。

  • If set to true, variables read in from config files will overwrite each other. Otherwise, the variables will be pushed onto an array. This is helpful if you want to store arrays of data in config file

  • 对于Spring Boot2.1,默认情况下禁用bean重写,这是一件好事。 然而,我确实有一些测试,其中我使用mockito用模拟实例替换bean。在默认设置下,使用这种配置的测试将由于bean重写而失败。 我发现唯一有效的方法是通过应用程序属性启用bean重写: 但是,我真的希望确保测试配置的bean定义设置最小,这一点将由spring在禁用重写的情况下指出。 我正在重写的bean是 在导入到

  • 我有一个使用Spring-Mongo集成的Spring应用程序。在主端配置XML中,我们有这样的东西来定义Mongo实例(有几个): 我想在Fongo的BDD套件配置中覆盖这一点,这样测试就不会使用真正的mongo。 我有点被“mongo:mongo”的具体设置搞得晕头转向。我以为你最终会得到一个com。mongodb。蒙哥,别这样。XML似乎指的是Spring MongoType? 我在BDD配

  • 在默认情况下加载的文件夹中有一个类型安全配置。 可以通过指定以下内容重写单个值: 将无法加载。相反,将加载resources文件夹中的原始文件。尝试以下技巧:在纱线上使用typesafe config和Spark也没有帮助。 当使用uberjar部署时,重写类型安全配置中的多个配置值似乎是普通(没有spark)程序的解决方案。问题仍然是如何使这一点产生火花。 同样通过的是: https://git