使用Spring JavaConfig的bean的初始化映射

时间:2016-01-17 14:58:31

标签: java spring dependency-injection spring-annotations

我的AbstractParent类包含自动变量fieldChild类,它扩展了AbstractParent。在我的应用程序中,我需要AbstractParent的子类映射来实现策略模式。

我使用Spring JavaConfig初始化我的应用程序。这是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;
    }

但是,来自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的字段等于null。在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;
    }
}

Class Child

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:这个问题经过了大量修改。现在它更抽象

1 个答案:

答案 0 :(得分:1)

我通过向@Configuration类添加注释Config来解决问题。没有这个注释,Spring bean之间的引用不起作用。省略@Configuration时,在 lite 模式下处理@Bean个方法,因此调用此方法只是简单的java方法调用

Spring @Bean doc

相关问题