2016-01-17 2 views
4

У меня есть класс AbstractParent с переменными field и Child, который расширяет AbstractParent. В моем приложении мне нужна карта подклассов AbstractParent для реализации шаблона стратегии.Инициализация карты боба с использованием Spring JavaConfig

Я запускаю свое приложение с использованием 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 имеет непустое поле, а поле вар 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: Этот вопрос был сильно изменен. Теперь это более абстрактно

+1

вы должны смотреть на спринтерском-тесте 'SpringJUnit4ClassRunner', это берет на себя материал, который вы делаете в 'setUp()' – leeor

+0

Из приведенной выше информации я не могу воспроизвести проблему. Можете ли вы изменить свой код, чтобы проблема могла быть успешно реплицирована. – ArunM

+0

ArunM, я добавил код. Вы можете просто скопировать его. –

ответ

1

Я решил проблему, добавив аннотацию @Configuration в класс Config. Ссылки на источники между ссылками не работают без этой аннотации. Когда @Configuration опущен, @Bean методов обрабатываются в облегченного режима, поэтому вызов этого метода является только простым методом Java призыванием

Spring @Bean doc