【6】Spring JavaConfig和常见Annotation
Java 5 的推出,加上当年基于纯 Java Annotation 的依赖注入框架 Guice 的出现,使得 Spring 框架及其社区也“顺应民意”,推出并持续完善了基于 Java 代码和 Annotation 元信息的依赖关系绑定描述方式,即 JavaConfig 项目。
基于 JavaConfig 方式的依赖关系绑定描述基本上映射了最早的基于 XML 的配置方式,比如:
1)表达形式层面
基于 XML 的配置方式是这样的:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd">
- <!-- bean定义 -->
- </beans>
而基于 JavaConfig 的配置方式是这样的:
- @Configuration
- public class MockConfiguration{
- // bean定义
- }
任何一个标注了 @Configuration 的 Java 类定义都是一个 JavaConfig 配置类。
2)注册 bean 定义层面
基于 XML 的配置形式是这样的:
<bean id="mockService" class="..MockServiceImpl"> ...</bean>
而基于 JavaConfig 的配置形式是这样的:
- @Configuration
- public class MockConfiguration {
- @Bean
- public MockService mockService() {
- return new MockServiceImpl();
- }
- }
任何一个标注了 @Bean 的方法,其返回值将作为一个 bean 定义注册到 Spring 的 IoC 容器,方法名将默认成为该 bean 定义的 id。
3)表达依赖注入关系层面
为了表达 bean 与 bean 之间的依赖关系,在 XML 形式中一般是这样的:
- <bean id="mockService" class="..MockServiceImpl">
- <property name="dependencyService" ref="dependencyService" />
- </bean>
- <bean id="dependencyService" class="DependencyServiceImpl" />
而在 JavaConfig 中则是这样的:
- @Configuration
- public class MockConfiguration {
- @Bean
- public MockService mockService() {
- return new MockServiceImpl(dependencyService());
- }
- @Bean
- public DependencyService dependencyService() {
- return new DependencyServiceImpl();
- }
- }
如果一个 bean 的定义依赖其他 bean,则直接调用对应 JavaConfig 类中依赖 bean 的创建方法就可以了。
在 JavaConfig 形式的依赖注入过程中,我们使用方法调用的形式注入依赖,如果这个方法返回的对象实例只被一个 bean 依赖注入,那也还好,如果多于一个 bean 需要依赖这个方法调用返回的对象实例,那是不是意味着我们就会创建多个同一类型的对象实例?
从代码表述的逻辑来看,直觉上应该是会创建多个同一类型的对象实例,但实际上最终结果却不是这样,依赖注入的都是同一个 Singleton 的对象实例,那这是如何做到的?
笔者一开始以为 Spring 框架会通过解析 JavaConfig 的代码结构,然后通过解析器转换加上反射等方式完成这一目的,但实际上 Spring 框架的设计和实现者采用了另一种更通用的方式,这在 Spring 的参考文档中有说明。即通过拦截配置类的方法调用来避免多次初始化同一类型对象的问题,一旦拥有拦截逻辑的子类发现当前方法没有对应的类型实例时才会去请求父类的同一方法来初始化对象实例,否则直接返回之前的对象实例。
所以,原来 Spring IoC 容器中有的特性(features)在 JavaConfig 中都可以表述,只是换了一种形式而已,而且,通过声明相应的 Java Annotation 反而“内聚”一处,变得更加简洁明了了。
那些高曝光率的 Annotation
至于 @Configuration,我想前面已经提及过了,这里不再赘述,下面我们看几个其他比较常见的 Annotation,便于为后面更好地理解 SpringBoot 框架的奥秘做准备。
1. @ComponentScan
@ComponentScan 对应 XML 配置形式中的 <context:component-scan> 元素,用于配合一些元信息 Java Annotation,比如 @Component 和 @Repository 等,将标注了这些元信息 Annotation 的 bean 定义类批量采集到 Spring 的 IoC 容器中。
我们可以通过 basePackages 等属性来细粒度地定制 @ComponentScan 自动扫描的范围,如果不指定,则默认 Spring 框架实现会从声明 @ComponentScan 所在类的 package 进行扫描。
@ComponentScan 是 SpringBoot 框架魔法得以实现的一个关键组件,大家可以重点关注,我们后面还会遇到它。
2. @PropertySource 与 @PropertySources
@PropertySource 用于从某些地方加载 *.properties 文件内容,并将其中的属性加载到 IoC 容器中,便于填充一些 bean 定义属性的占位符(placeholder),当然,这需要 PropertySourcesPlaceholderConfigurer 的配合。
如果我们使用 Java 8 或者更高版本开发,那么,我们可以并行声明多个 @PropertySource:
- @Configuration
- @PropertySource("classpath:1.properties")
- @PropertySource("classpath:2.properties")
- @PropertySource("...")
- public class XConfiguration{
- ...
- }
如果我们使用低于 Java 8 版本的 Java 开发 Spring 应用,又想声明多个 @PropertySource,则需要借助 @PropertySources 的帮助了,代码如下所示:
- @PropertySources({ @PropertySource("classpath:1.properties"), @PropertySource("classpath:2.properties"), ...})
- public class XConfiguration{
- ...
- }
3. @Import 与 @ImportResource
在 XML 形式的配置中,我们通过 <import resource="XXX.xml"/> 的形式将多个分开的容器配置合到一个配置中,在 JavaConfig 形式的配置中,我们则使用 @Import 这个 Annotation 完成同样目的:
- @Configuration
- @Import(MockConfiguration.class)
- public class XConfiguration {
- ...
- }
@Import 只负责引入 JavaConfig 形式定义的 IoC 容器配置,如果有一些遗留的配置或者遗留系统需要以 XML 形式来配置(比如 dubbo 框架),我们依然可以通过 @ImportResource 将它们一起合并到当前 JavaConfig 配置的容器中。
【6】Spring JavaConfig和常见Annotation的更多相关文章
- Spring JavaConfig实例
从Spring 3起,JavaConfig功能已经包含在Spring核心模块,它允许开发者将bean定义和在Spring配置XML文件到Java类中. 但是,仍然允许使用经典的XML方式来定义bean ...
- Spring应用开发常见规范
1.Spring应用开发常见包命名规范 controller:控制器 service:服务-接口 impl:服务-实现 integration sao:调用其他模块的,把feign的调用放到这个下面 ...
- Spring - IoC(8): 基于 Annotation 的配置
除了基于 XML 的配置外,Spring 也支持基于 Annotation 的配置.Spring 提供以下介个 Annotation 来标注 Spring Bean: @Component:标注一个普 ...
- Spring重温(二)--Spring JavaConfig
1.从Spring 3起,JavaConfig功能已经包含在Spring核心模块,它允许开发者将bean定义和在Spring配置XML文件到Java类中.但是,仍然允许使用经典的XML方式来定义bea ...
- Spring JavaConfig
以前,Spring推荐使用XML的方式来定义Bean及Bean之间的装配规则,但是在Spring3.0之后,Spring提出的强大的JavaConfig这种类型安全的Bean装配方式,它基于Java代 ...
- Spring JavaConfig @Import实例
一般来说, 需要按模块或类别 分割Spring XML bean文件 成多个小文件, 使事情更容易维护和模块化. 例如, <beans xmlns="http://www.spring ...
- Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 公司需要人.产品.业务和方向,方向又要人.产品.业务和方向,方向… 循环』 本文提纲一. ...
- java之Spring(AOP)-Annotation实现添加切面
我们已经知道之前的切面添加方式(动态代理),是定义了一个实现了InvocationHandler接口的Handlerservice类,然后 在这个类内部写好切面逻辑,包括切面放置的位置,很显然下面的这 ...
- 正确实现用spring扫描自定义的annotation
背景在使用spring时,有时候有会有一些自定义annotation的需求,比如一些Listener的回调函数. 比如: @Service public class MyService { @MyLi ...
- Spring配置之context:annotation与、component-scan以及annotation-driven
spring boot帮助我们隐藏了大量的细节,有些配置spring boot都是开启的,因此当我们查看遗留项目使用spring时候遇见问题一定细心排查 <!-- context:annotat ...
随机推荐
- 基于stm32H730的解决方案开发之SD卡的读写调试
一 概述 在嵌入式小系统领域,SD卡存储是一个非常重要的功能.可从难度上,它又是非常难的.因为它涉及到两个大的功能点,一个是文件系统,这个难度非一般.另外一个是sd卡的底层驱动.涉及到的接口多,所以也 ...
- 不可不知道的python装饰器
前记 python小白,估计很多没用过这个高级功能吧,当你用了它之后就会发现,真是非常好用喔. 装饰器本质上是一个 Python 函数或类,它可以让其他函数或类在不需要做任何代码修改的前提下增 ...
- day06-IO流应用01
Java坦克大战06 8.IO流应用01 坦克大战6.0版 增加功能: 防止敌人坦克重叠运动 记录玩家的成绩(累计击毁坦克数),存盘退出 记录当时的敌人坦克坐标,存盘退出 玩游戏时,可以选择是开新游戏 ...
- 《TencentNCNN系列》 之param文件(网络结构文件)格式分析
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- 大年学习linux(第一节)
Linux学习笔记 一.常用命令 终端快键键: Ctrl+a/home 切换到命令行开始 Ctrl+e/end 切换到命令行末尾 Ctrl+i 清除屏幕内容,效果等同于clear Ctrl + u 清 ...
- Spring Boot学习日记8
学习了yaml文件的配置 <server> <port>8081<port> </server> # k-v键值对 name: xiaoqi #相当于n ...
- 可变形卷积系列(一) 打破常规,MSRA提出DCNv1 | ICCV 2017 Oral
论文提出可变形卷积帮助模型高效地学习几何变换能力,能够简单地应用到分类模型和检测模型中,思想新颖,效果显著,十分值得学习 来源:晓飞的算法工程笔记 公众号 论文: Deformable Convo ...
- 化腐朽为神奇的QueryMapping
化腐朽为神奇的QueryMapping 老车除了报废没别的方法? 应用系统就像老车,经过十几二十年的使用,积累了大量里程数据,但是英雄迟暮,反应迟钝,时不时还要病休.但就这样报废,推到重来,如果没有充 ...
- PyCharm字体大小快捷键设置(“ctrl+滚轮”实现字体的随时放大和缩小)
前言:我们在使用PyCharm工具编写Python代码的时候,希望能够随时放大缩小字体,而PyCharm默认是没有设置快捷键的,我们可以自己设置,下面就教大家如何设置. 分为两步设置: PyCharm ...
- SpaceDesk怎么连接平板/PC(提高生产力,扩展副屏)
1.下载安装 分为安卓端和PC端,两个设备都需要安装对应的软件. SpaceDesk官网 https://link.zhihu.com/?target=http%3A//spacedesk.net/ ...