我正在使用弹簧靴,它在启动时会自动扫描豆子。
通常我知道它会扫描标有@ service
,@ repository
和@ component
的bean。
比@ Configuration
我们有@ Bean
注释。
有什么方法可以实现一些接口,如果包名称不同,它将成为扫描的一部分
@SpringBootApplication(scanBasePackages = "xyz.yah.*")
问题是我的库有不同的包名称,更改scanBasePackages属性变得有点麻烦所以我想知道我的bean是否可以实现一些接口,它立即成为自动扫描的一部分。任何解决方案?
也不确定我是否只是实施Aware界面就足以有资格进行自动扫描。
答案 0 :(得分:0)
在这方面考虑更多,这应该适合你。然而,它是额外的黑魔法,并隐藏了bean的创建位置/方式,命名,范围等等。我建议创建配置类等。
使用https://github.com/ronmamo/reflections,
Reflections reflections = new Reflections("com.mycompany.basepackage");
Set<Class<? extends MyInterface>> classes = reflections.getSubTypesOf(MyInterface.class);
将为您提供一组所有类的界面。这可以拉到一起,在启动时动态加载bean,如下所示,
@Configuration
public class AwareConfig implements BeanDefinitionRegistryPostProcessor {
private static final Logger LOG = LoggerFactory.getLogger(AwareConfig.class);
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
Reflections reflections = new Reflections(this.getClass().getPackage().getName());
Set<Class<? extends Aware>> classes = reflections.getSubTypesOf(Aware.class);
classes.stream().forEach(clazz -> {
try {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(Class.forName(clazz.getName())).setLazyInit(false);
((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(clazz.getName(),
builder.getBeanDefinition());
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
LOG.info("Creating - {} bean", clazz.getName());
});
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry arg0) throws BeansException {
//NoOp
}
}
根据用例,您可以使用其他类型的bean后处理器。也不必是一个接口可以通过注释驱动它,允许您更容易指定参数而不是通过接口实现它们。
我在这里创建了一个工作示例,
https://github.com/Flaw101/dynamically-load-spring-bean
请记住这很简单,你的bean越复杂,加载和注入它们的问题就越多。
我已经更新了示例,将两个动态bean注入service
类。