spring boot2 (二)五个不得不会的底层注解

挺感谢雷老师的spring boot1,spring boot2两个教程的。除了讲了spring boot版本带来的差异外,讲法也略有不同。我个人反正觉得spring boot2相对于1来讲更适合全览和概括。这里讲到的五个比较底层的注解,而且其在自动配置上起了很大的作用(不仅仅是spring boot的注解,而是spring的),这里详细介绍一下。
这里划重点一句话:只有在容器中的组件才可以拥有SpringBoot提供的各种强大的功能!!!!

@Configuration

这个注解是告诉springboot这是一个配置类,等同于以前spring的配置文件
它里面可以定义多个bean,相当于之前xml文件中的<bean>标签。
默认的这个@bean注解修饰的方法:方法名就是组件的id(这里也可以自己自定义bean中写想要的组件id)。方法的返回类型就是组件的类型,返回值的就是组件在容器中存在的实例。
下面是一个简单的demo:

  1. 在@Configuration修饰的类中注入两个bean


    config类

    如上代码,sysDriver和sysUser就是两个普通的实体类,然后我在被@Configuration修饰的类中注入了两个bean分别是这个类型。为了测试出效果我特意一个用默认的方式,一个指定了组件id。

@Configuration
public class MyConfig {
    
    @Bean
    public SysDriver sysDriver() {
        SysDriver sysDriver = new SysDriver();
        sysDriver.setId(2);
        sysDriver.setName("lisi");
        sysDriver.setSex(1);
        return sysDriver;
    }
    @Bean("user")
    public SysUser sysUser() {
        SysUser sysUser = new SysUser();
        sysUser.setId(1);
        sysUser.setName("lisijia");
        sysUser.setAge(26);
        return sysUser;
    }
}

下面我们启动项目看看容器中是不是有这两个组件了:

打印容器中组件名

容器中确实有了这两个组件

其实到这我们就算测试成功了,连名称都和我们意料的一样,但是闲着也是闲着,我们可以继续看下容器中的实例是不是和我们放进去的一样:
组件类型和输出

事实证明这个和我们放进去的是一样的。所以说我们上面说的默认方法名称是id,返回类型是组件的类型,返回对象就是组件实例得到证实了!
而且这个组件应该是唯一的,也就是我获取几次得到的都应该是一个对象,下面我们再测试一下:
组件是单例的

我这里用的==。也就是只有一个对象才会是true,所以说容器中获得的组件是单例的。
当然了,配置类本身也是组件。这个也很好理解。


重点来了,!!相对于Spring boot1.x。2.x有一个很明显的变化:在@Configuration中多了一个属性---代理bean方法:proxyBeanMethods,默认是true


这个属性的作用比较好理解:上面属性是代理bean方法。因为配置类本身就是一个类,所以理论上我们是可以通过这个配置类直接调用这个被@bean注释的方法。如下用法:

从config类中取出来的也是这个单例组件

而当上面说的那个bean代理属性值是false的时候,那么外部访问调用的和组件里的就不是一个对象了。如下截图:
代理bean属性false

这里的逻辑是当myConfig的属性proxyBeanMethods是true。那么它本身已经被增强了,本身就是代理对象了,这样通过它访问的对象都会去容器中找是不是有这个组件,如果有就会返回这个组件,没有才生成新的。你是如果proxyBeanMethods属性是false那么他就是普通的组件了,外部访问的话会新生成实例。
这里有两个概念:full和lite。轻量级和重量级。首先full的话调用性能会很慢,因为每次调用都要先去组件中寻找是不是存在这个组件。而lite则不用,每次调用就直接new,不用检查。而这个功能适用于组件依赖:
比如config中有两个组件A,B。并且在A中调用了B。
如果设置proxyBeanMethods是true。那么A中的B会保持单例的,就是容器中的那个实例。否则A中的B不会是容器中的那个。
据说如果不存在组件依赖的情况我们大多数时候会把其设置为false,使得性能更好,但是存在组件依赖的时候还是要设置为true保证程序的正确性的。

@Import

这个也是给容器中添加组件,它的参数是个class数组,可以给容器中导入很多组件。给容器中自动创建出参数类型的组件。如下图:


import导入组件

很明显,这个import注解中的Test,Test1,Test2都自动纳入spring容器中了。而且默认组件的id就是全类名。

@Confitional

这个是条件装配,之前说过好多次了,这个是个基本注解,可以演变成好多注解。如下图:


@Conditional衍生注解

其各种条件满足的条件都是字面上的意思,比如要有某个bean,要没有某个bean,要是web环境,要是存在某个类,要不存在某个类,反正见名知意,我觉得也没必要一一细说了,之前有一个带中文的图在spring boot1.x版本的记笔上,我也懒得再翻出去贴上了,一个个注解用多了就直到啥意思了。这个注解就这样了。

@ImportResource("/path")

类似于第二个注解@Import,只不过这个是导入某个配置文件中的组件(虽然我有点理解不了为什么先写到xml上再解析,不过可能维护老项目或者三方项目都会遇到吧)。如下demo:


配置文件生效

我在配置文件中用xml配置了个组件,id是lsj。然后正常来讲这个配置文件是不会起作用的,但是我把这个@ImportResource(“/文件路径”)放在配置类上,这个配置文件就会起作用。

@ConfigurationProperties

这个其实其实就是配置绑定。指定前缀的配置属性会绑定到当前类的属性中。
然后想要给某个类绑定某些属性,只要指定前缀和属性名称,然后在类上先纳入spring管理(也就是放到容器中),然后用配置绑定这个注解@ConfigurationProperties绑定指定前缀就可以了(这里默认在application.properties/yml中找)
如下demo:

配置绑定

我把SysUser这个类纳入容器管理并且绑定配置文件中的user.bean前缀的属性。
所以user.bean.id绑定在了id上,同理user.bean.age绑定到age属性。user.bean.name绑定在name属性上。最终我输出容器中叫做wfs这个id的组件,结果是我们配置文件配置的内容。修改配置文件重启组件中值也会变化的。
而且我这里还遇到一个好玩的事,我本来想绑定在user.这个前缀上的,但是我发现user.name=xxx我怎么设置都不起作用,输出的值都是我笔记本上用户的名称。。。所以说一个合理的事实:user.name被别的东西绑定了已经,而且优先级高于我这个配置文件(关于配置文件的优先级我之前记过笔记,估计以后还会整理)。反正也算是一个小小的惊喜吧,然后这种方式配置绑定就这样了。
还有一种绑定是开启配置绑定功能并且将其自动注册到容器中。总而言之:

@EnableConfigurationProperties(开启自动绑定(找类上的那个@ConfigurationProperties注解生效,并且将类纳入容器))
@ConfigurationProperties

等价于

@Component(五大组件注解都可以)
@ConfigurationProperties

上面说了第二种实现,下面是第一种实现的demo:

第二种实现方式

有一点需要注意:这种方式虽然也纳入容器中了,但是bean的id是默认的,反正我是在所有的bean中找的。。规律应该是配置文件前缀-全类名。
感兴趣的可以自己试试。
到这里,这五个注解就讲完了,有的说的多点,有的说的少点,反正我个人感觉都是常用又实用的。这些都是看spring boot源码所必要的基本功。以后会常常遇到,如果暂时觉得记不住也问题不大,看一段时间源码都自然而然的记住啦!
本篇笔记就记到这里,如果稍微帮到你了记得点个喜欢点个关注,也祝大家工作顺顺利利!生活健健康康吧~!今日份毒鸡汤:除非付出行动,否则口说无凭,没有人能通过祈祷试图改变人生!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • 1 注解 1.1 定义 Annotation(注解),用于为Java代码提供元数据。简单理解注解可以看做是一个个标...
    Java架构阅读 576评论 0 1
  • Spring Boot使用过程中,经常需要和很多注解打交道。也是我们常说的注解编程。所以接下来我们对Spri...
    tuacy阅读 1,596评论 0 11
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,485评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,551评论 0 11
  • 可爱进取,孤独成精。努力飞翔,天堂翱翔。战争美好,孤独进取。胆大飞翔,成就辉煌。努力进取,遥望,和谐家园。可爱游走...
    赵原野阅读 2,715评论 1 1