Spring组件扫描的用例

该博客的普通读者知道我是Spring框架的大力支持者,但是我对应该使用它的方式持肯定的态度。 例如,我赞成显式对象实例化和显式组件连接,而不是自注释类,组件扫描和自动装配。

概念

尽管许多Spring开发人员都使用了这些概念,但是我的经验告诉我它们并不总是被完全理解。 一些解释是为了命令。

自注释类

自注释类是定义类如何通过Spring对类本身的注释进行实例化的类。 @Component @Controller@Service @Controller@Service @Controller@Repository是大多数Spring项目中常见的自注释类。

@Component
classMySelfAnnotatedClass{}

自注释类的主要缺点是类与Bean之间的硬耦合。 例如,不可能像显式创建那样实例化2个相同类的单例bean。 更糟糕的是,它将类也耦合到Spring框架本身。

注意, @Configuration类也被认为是自注释的。

元件扫描

需要在上下文中列出和注册自注释类。 可以明确地做到这一点:

@Configuration
classMyConfig{

    @Bean
    funmyClass()=MySelfAnnotatedClass()
}

但是,最普遍的选择是让Spring框架在项目类路径上搜索每个自注释的类,然后根据注释对它们进行注册。

@Configuration@ComponentScan
classMyConfig

自动接线

一些bean需要依赖项才能被初始化。 将依赖项连接到依赖项bean可以是:

  • 明确的:告诉哪个bean将满足依赖关系是开发人员的责任。
  • 隐式(或自动):Spring框架负责提供依赖关系。 为此,单个Bean必须符合条件。

关于第二种选择,请重新阅读我的旧帖子以了解相关问题。

但是,有时无法避免自动装配。 当豆Bean1在配置片段定义Config1取决于豆Bean2在片段定义Config2 ,唯一可能的喷射选项自动装配。

@Configuration
classConfig2{

    @Bean
    funbean2()=Bean2()
}

@Configuration
classConfig1{

    @Bean@Autowired
    funbean1(bean2:Bean2)=Bean1(bean2)
}

在以上代码段中,使用了自动装配而不使用自注释类。

重新发明轮子

本周,我发现自己在旧版非Spring Boot应用程序中重新实现了Spring Boot的执行器。

该体系结构非常简单:HTTP端点返回通过Jackson库序列化的Java对象(或它们的列表)。 每个端点可能返回不同的对象,并且每个端点都可以使用自定义序列化程序进行序列化。

我已经按照每个端点打包的方式组织了该项目(与每层打包相反),并且已经提供了多个端点。 我希望人们为其他目标做出贡献,并且我希望它尽可能简单。 特别是,它们应仅:

  1. 声明控制器
  2. 声明配置类
  3. 实例化Jackson序列化器

其余的应该由我编写的通用代码来处理。

正确使用自动接线

通过使用位于项目主程序包中的主配置类上的@ComponentScan ,可以轻松处理控制器和配置类。 但是串行器呢?

Spring能够将注册到上下文中的特定类的所有bean收集到一个列表中。 这意味着每个程序包都将独立声明其序列化程序,并且通用代码可以处理注册:

@Configuration@EnableWebMvc@ComponentScan
classWebConfiguration:WebMvcConfigurerAdapter(){

    @Autowired
    privatelateinitvarserializers:List<StdSerializer<*>> (1)

    overridefunconfigureMessageConverters(converters:MutableList<HttpMessageConverter<*>>){
        converters.add(MappingJackson2HttpMessageConverter().apply{
            objectMapper.registerModule(SimpleModule().apply{
                serializers.forEach{addSerializer(it)}
            })
        })
    }
}
  1. 魔术在这里发生。 该配置类已经编写完毕,新的程序包不需要做任何事情,序列化程序将成为列表的一部分。

这是一个这样的配置类的示例,声明一个序列化器bean:

@Configuration
classFooConfiguration{

    @Bean
    funfooSerializer()=FooSerializer()
}

classFooSerializer:StdSerializer<Foo>(Foo::class.java){
    ...
}

更好的是,如果需要将软件包进一步模块化为成熟的JAR,则此设置将以完全相同的方式工作,而无需进行任何更改。

结论

更好地了解自注释类,组件扫描和自动装配对所有Spring开发人员都是有益的。

而且,尽管它们在“标准” bean类中有很多缺点,但在配置类的范围内这样做不仅是完全可以接受的,而且甚至是一个优点。 在按功能逐包设计的项目中,它改善了模块化和去耦性。

翻译自: https://blog.frankel.ch/use-case-spring-component-scan/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值