【问题标题】:Initialization map of beans using Spring JavaConfig使用 Spring JavaConfig 的 beans 的初始化映射
【发布时间】:2016-04-22 17:45:38
【问题描述】:

我有 AbstractParent 类和自动装配变量 fieldChild 类,扩展 AbstractParent。在我的应用程序中,我需要 AbstractParent 的子类映射来实现策略模式。

我使用 Spring JavaConfig 初始化我的应用程序。这是配置类的一部分:

    @Bean
    public String field() {
        return "Field of abstract parent class";
    }

    @Bean
    public Child child() {
        return new Child();
    }

    @Bean
    public HashMap<String, Object> initMap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("child", child());
        return map;
    }

但是在 HashMap 初始化后,子节点有未初始化的字段。我发现了一些有趣的事情。下面是我测试的一部分:

@Before
public void setUp() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Config.class);
    context.refresh();
    child = context.getBean(Child.class);
    map = context.getBean(HashMap.class);
}
@Test
public void test() {
    assertNotNull(child.getField());
    System.out.println(child);
    AbstractParent childFromMap = map.get("child");
    System.out.println(childFromMap);
    assertNotNull(childFromMap);
    System.out.println(childFromMap.getField());
    assertNotNull(childFromMap.getField()); //FAIL =(
}

变量child具有非空字段,而var childFromMap的字段等于空。在 println 我可以看到,它是两个不同的对象。所以我有建议,地图的对象不是在 Spring 的上下文中创建的。

所以我的问题: 是否可以使用在 JavaConfig 中创建的对象填充地图?

以下是我的问题的完整代码,您可以复制\粘贴并重现它。

类 AbstractParent

import org.springframework.beans.factory.annotation.Autowired;

public abstract class AbstractParent {

    @Autowired
    protected String field;

    protected abstract void method();

    protected String getField() {
        return field;
    }
}

班级孩子

public class Child extends AbstractParent{

   @Override
   protected void method() {
       System.out.println(field);
   }
}

TestConfig 和测试

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

import java.util.HashMap;
import java.util.Map;

import static org.junit.Assert.assertNotNull;

public class TestConfig {
private Child child;
private Map<String,AbstractParent> map;
static class Config {

    @Bean
    public String field() {
        return "Field of abstract parent class";
    }

    @Bean
    public Child child() {
        return new Child();
    }

    @Bean
    public HashMap<String, Object> initMap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("child",child());
        return map;
    }

}

@Test
public void test() {
    assertNotNull(child.getField());
    System.out.println(child);
    AbstractParent childFromMap = map.get("child");
    System.out.println(childFromMap);
    assertNotNull(childFromMap);
    System.out.println(childFromMap.getField());
    assertNotNull(childFromMap.getField());
}

@Before
public void setUp() {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    context.register(Config.class);
    context.refresh();
    child = context.getBean(Child.class);
    map = context.getBean(HashMap.class);
}

}

PS:这个问题被大量修改。现在它更抽象了

【问题讨论】:

  • 你应该看看 sprint-test SpringJUnit4ClassRunner,这会处理你在 setUp() 中所做的事情
  • 根据上面给出的信息,我无法复制问题。请您修改您的代码,以便可以成功复制问题。
  • ArunM,我添加了一些代码。你可以简单地复制粘贴它。

标签: java spring dependency-injection spring-annotations


【解决方案1】:

我通过将注释@Configuration 添加到Config 类来解决问题。如果没有此注解,Spring bean 间引用将无法工作。当@Configuration省略时,@Bean方法以lite模式处理,所以该方法的调用只是简单的java方法调用

Spring @Bean doc

【讨论】:

    猜你喜欢
    • 2020-01-14
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 2014-02-10
    相关资源
    最近更新 更多