Как переопределить компонент spring, определенный в xml, с помощью аннотаций?
у меня есть в зернах overrideBean
определена в spring.xml
который я хотел бы переопределить с помощью аннотаций. Я попытался переопределить bean следующим образом:
@Configuration
@ImportResource({"/spring.xml"})
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DdwMain.class);
Object o = context.getBean("overrideBean");
// o should be null but it is not
}
@Bean(name="overrideBean")
public OverrideBean overrideBean() {
return null;
}
}
используя приведенный выше код, Боб из spring.xml
config всегда создается и возвращается context.getBean
звонок.
компонент можно переопределить, включив другой файл конфигурации XML в @ImportResource
однако я предпочел бы найти решение, используя аннотации, было бы чище.
2 ответов
обычно зарегистрированные в xml бобы имеют приоритет. Таким образом, вы можете переопределить аннотированные бобы с XML-настроенными, но вы пытаетесь сделать это наоборот. Вы не можете использовать другое имя компонента и выбрать его среди нескольких кандидатов, используя @ Qualifier аннотации?
большую часть времени объединение xml с автосканированием подвержено ошибкам.
Я работаю в старом приложении (spring 3.1.1), настроенном через xml, но мне нужно было перетасовать некоторую конфигурацию для тестирования, не отклоняясь слишком далеко от производственной конфигурации. Мой подход заключается в использовании BeanPostProcessor.
package myapp.test;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import myapp.spring.config.ComplexSpringConfiguration;
/**
* Closely resembles production configuration for testing
* @author jim
*/
@Configuration
@ImportResource("file:src/main/webapp/WEB-INF/spring-servlet.xml")
@Import(ComplexSpringConfiguration.class)
public class TestConfig {
final Logger logger = LoggerFactory.getLogger(getClass());
static {
System.setProperty("env.test", "system");
}
//Override templateLoaderPath with something amenable to testing
@Bean
public BeanPostProcessor beanPostProcessor(){
return new BeanPostProcessor(){
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//Override templateLoaderPath with something amenable to testing
if(beanName.equals("freemarkerConfig")) {
logger.debug("overriding bean with name:" + beanName);
FreeMarkerConfigurer fc = new FreeMarkerConfigurer();
fc.setTemplateLoaderPath("file:src/main/webapp/WEB-INF/freemarker");
bean = fc;
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
};
}
@Bean
public ServletContext servletContext(){
MockServletContext mockContext = new MockServletContext();
mockContext.setContextPath("/myapp");
return mockContext;
}
}