Spring 使用 @ComponentScan 按名称自动装配,但在 属性 上不使用 @Autowired
Spring autowire by name with @ComponentScan but without @Autowired on property
刚刚从基于 xml 的配置迁移到 Spring 4.3 中基于 java 的配置。
在 xml 我们有
<beans ... default-autowire="byName">
<component-scan .../>
...
</beans>
在 Java 类 我们在字段上没有 @Autowired 注释:
@Component
public class MyService {
private OtherService otherService;
// +setters
....
}
以前在 xml 中使用 default-autowire="byName"
自动装配工作得很好。
现在,当移动到 JavaConfig 时,我找不到启用组件扫描的默认自动装配机制的方法。
使用名称自动装配,无需 @Autowired 注释即可进行装配。
使用@Bean(autowire=BY_NAME) 我可以定义一个bean 以按名称自动装配,但我需要组件扫描机制。不要用@Bean 工厂方法定义所有bean。
此外,我尽量不在所有 类 的所有字段中添加 @Autowired 注释。改变太多了。
我现在的问题是:如何告诉组件扫描按名称自动装配找到的 bean?
我不知道我是否明白你想做什么,但是Spring支持@Qualifier and @Resource注解:
@Resource takes a name attribute, and by default Spring interprets that value as the bean name to be injected. In other words, it follows by-name semantics
一个解决方案是使用 BeanFactoryPostProcessor 更新 bean 定义,以将所有 bean 标记为按名称自动装配,例如:
public class AutowireScannedByNameBeanPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach(name -> {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
if (beanDefinition instanceof ScannedGenericBeanDefinition) {
((ScannedGenericBeanDefinition) beanDefinition).setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
}
});
}
}
我还是很好奇 spring 中是否有设置可以做到这一点。
刚刚从基于 xml 的配置迁移到 Spring 4.3 中基于 java 的配置。
在 xml 我们有
<beans ... default-autowire="byName">
<component-scan .../>
...
</beans>
在 Java 类 我们在字段上没有 @Autowired 注释:
@Component
public class MyService {
private OtherService otherService;
// +setters
....
}
以前在 xml 中使用 default-autowire="byName"
自动装配工作得很好。
现在,当移动到 JavaConfig 时,我找不到启用组件扫描的默认自动装配机制的方法。
使用名称自动装配,无需 @Autowired 注释即可进行装配。
使用@Bean(autowire=BY_NAME) 我可以定义一个bean 以按名称自动装配,但我需要组件扫描机制。不要用@Bean 工厂方法定义所有bean。
此外,我尽量不在所有 类 的所有字段中添加 @Autowired 注释。改变太多了。
我现在的问题是:如何告诉组件扫描按名称自动装配找到的 bean?
我不知道我是否明白你想做什么,但是Spring支持@Qualifier and @Resource注解:
@Resource takes a name attribute, and by default Spring interprets that value as the bean name to be injected. In other words, it follows by-name semantics
一个解决方案是使用 BeanFactoryPostProcessor 更新 bean 定义,以将所有 bean 标记为按名称自动装配,例如:
public class AutowireScannedByNameBeanPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach(name -> {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
if (beanDefinition instanceof ScannedGenericBeanDefinition) {
((ScannedGenericBeanDefinition) beanDefinition).setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
}
});
}
}
我还是很好奇 spring 中是否有设置可以做到这一点。