Spring 通过实现 Aware 接口注册 bean

Spring register bean by implementating Aware interface

我正在使用 spring 引导程序,它会在启动期间自动扫描 bean。 通常我知道它会扫描标有@service、@repository 和@component.

的bean

比起@Configuration我们有@Bean注解。

有什么方法可以实现一些接口,如果包名称不同,它将成为扫描的一部分,这是在 @SpringBootApplication(scanBasePackages = "xyz.yah.*")

问题是我的库有不同的包名,更改 scanBasePackages 变得有点麻烦 属性 所以我想知道我的 bean 是否可以实现一些接口,通过它它立即成为自动扫描的一部分。有什么解决办法吗?

也不确定我是否只实现 Aware 接口就足以符合自动扫描的条件。

仔细考虑一下,这应该对你有用。然而,这是额外的黑魔法,where/how bean 的隐藏正在创建、命名、范围等。我建议创建配置 classes 等

使用 https://github.com/ronmamo/reflections

Reflections reflections = new Reflections("com.mycompany.basepackage");    
Set<Class<? extends MyInterface>> classes = reflections.getSubTypesOf(MyInterface.class);

将为您提供一组所有 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 post 处理器。也不一定是接口可以通过注释驱动它,允许您更轻松地指定参数而不是通过接口实现它们。

我在这里创建了一个工作示例,

https://github.com/Flaw101/dynamically-load-spring-bean

请记住,这相当简单,您的 bean 越复杂,加载和注入它们的问题就越多。

我更新了示例,将两个动态 bean 注入 service class。