不那么冗长@Bean

Less verbose @Bean

我们将 @Configuration classes 与许多 @Bean 注释方法一起使用,这些方法本质上是这样的:

@Bean
public TeamContactIndexer teamContactIndexer(GroupService groupService, ContactCrudService contactCrudService, ContactRetrieveService contactRetrieveService) {
    return new TeamContactIndexer(groupService, contactCrudService, contactRetrieveService);
}

所以这个 returns 一个新 bean 并通过方法参数将其他 spring 声明的东西按名称注入构造函数。

我知道减少冗长的唯一方法是用 @Component 注释 bean,用 @Autowired.

注释构造函数

对于许多人来说,这是完全可以接受的,但我不想在我的代码中乱扔 Spring 注释,只是为了方便管道,并在 @ 中完全 spring 自由业务逻辑和管道代码之间保持清晰的分离配置注释 classes。我将它们视为我们在 xml.

中所做的更安全、更简洁的替代品

不过,如果我能去就好了...

@Bean
public TeamContactIndexer teamContactIndexer;

... 并让 spring 弄清楚它需要自动装配那个 class 的构造函数(100% spring 免费)来生成 bean。据我所知,Spring 目前不支持此功能,尽管据我所知应该很容易做到。我是不是遗漏了什么,或者真的没有办法在我的 @Configuration classes 中对构造函数调用进行微观管理(除了在我的代码中乱加注释)?我的绝大多数 @Bean 方法应该可以像这样轻松替换。

更新

@bezmax 在这里提供了一种可行的方法,即使用组件扫描注释。

@Configuration @ComponentScan( basePackages={"com.github.jsonj.tools"}, includeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = {JsonParser.class})}) public class JsonParserConfig { }

我已经使用上面的方法为我使用的库中没有注释的 bean 提供了 bean 定义。这取代了我之前使用的 @Bean 注释工厂方法。它仍然有些冗长,但至少您可以输入逗号分隔的 classes 列表。这个用例的默认类型是错误的,所以你必须指定它;同样,包定义是必需的,即使它可以从过滤器上的 class 推断出来。

恕我直言,Spring 中还有明显改进的余地,即提供一个仅采用逗号分隔的 classes 列表的注释。因此,无需扫描包,只需列出要初始化的 bean classes。通过构造函数自动装配可能仍然存在一些棘手的问题。

此功能在 Spring 4.3(尚未发布)中实现。

您可以在 changelog(参见 6.1)

中阅读更多相关信息

已添加:

关于自动注册未注释的 类,似乎有一种灵活的方法可以使用 @ComponentScan 注释来实现。此注释允许您指定一组包含过滤器,当在 类 上匹配时,这些过滤器会自动注册为 beans。我实际上并没有尝试对这个过滤器使用更复杂的规则,看起来你有几个选项(查看@ComponentScan 上的文档)但最简单的是这样的:

@Configuration
@ComponentScan(
        value = "some.package.path",
        includeFilters = {
                @Filter(type = ASSIGNABLE_TYPE, value = {
                        MyClass1.class,
                        MyClass2.class,
                        MyClass3.class
                })
        })
public class WebConfig extends WebMvcConfigurerAdapter {
...