【Java Web】-> Spring Boot -> 详解底层注解

Ⅰ @Configuraion

我先定义一个简单的实体类 Book 。完成基本的 setter 方法和 toString 方法 。
在这里插入图片描述
在 Spring IOC 中,我们可以通过配置 xml 文件和注解两种方式来完成一个类的注入,也可以通过配置类生成对应的 Bean,我们在配置类中就会使用到 @Configuraion 注解。

【Java Web】 -> Spring 5 ->IOC 操作 -> Bean 管理 ->关于 IOC 的一切就在这里了

我们来看一下 Spring Boot 中的 @Configuraion 注解。
在这里插入图片描述

通过@Configuraion@Bean 注解,我们可以创建出一个 Bean 的实例,默认组件的 id 就是方法名称,但是我们也可以重新定义自己想要的 id 名。
在这里插入图片描述

这样 id 就被改成了 bbb,而不是方法名。

注意这时我们在容器中注册的组件默认就是单实例的,无论我们获取多少次,都会是同一个对象。

在这里插入图片描述
并且,我们的配置类本身也是一个组件,它是可以被获得的。
在这里插入图片描述
在 Spring Boot 2 中,还增加了一个属性 proxyBeanMethods,可以看到这个属性是默认为 true 的。
在这里插入图片描述
这个属性表示是不是代理 bean 的方法。大家可以看我上面输出的 MyConfig 类的图。
在这里插入图片描述
MyConfig 类的对象其实是被 CGLIB 增强了的对象,简单来说就是它是一个代理对象。对于一个代理方法,Spring Boot 会检查它的方法所生成的对象,如果容器中已经存在了,就直接返回,不存在才进行创建。这就使得所注册的组件都是单例的。

现在我们将这个属性改成 false ,再来做一下测试。
在这里插入图片描述
测试结果如下
在这里插入图片描述
可以看到,生成的两个组件的对象并不相等,说明它们是两个不同的对象。并且,生成的 MyConfig 对象也是它本身的对象,并不是代理对象。

这就引出了 Spring Boot 的两个配置,全配置 Full轻量级配置 Lite

proxyBeanMethodstrue 时,为全配置,此时配置类中每一个注册组件的方法,Spring Boot 都会在容器中查找组件,如果找到了就直接返回;

proxyBeanMethodsfalse 时,为轻量级配置,此时每一次调用配置类中的注册组件方法,都会产生一个新的对象。

通过这两种配置,可以解决 组件依赖 的问题。

比如这时我们再定义一个类,出版社 Press
在这里插入图片描述
然后我们让 Book 类依赖它。在 Book 类中增加相应的 Getter 和 Setter。
在这里插入图片描述
MyConfig 类中,对 Book 进行注入。
在这里插入图片描述
现在我们设置 proxyBeanMethods = true ,然后做一个测试。
在这里插入图片描述
可以看到,从容器中取得的 Book 类的对象,它的 press 和 直接从容器中取得的 press 是同一个。

而当我们将全配置改成轻量级配置之后,可以看到它们就不是同一个对象了。
在这里插入图片描述
当使用的是轻量级配置的时候,Spring Boot 不用每次都从容器中检查,而是直接创建,这样就比全配置每次都要检查一下快很多。

Ⅱ @Import

@Import 用于导入一个组件,可以写在容器中任意一个组件上。我们看一下它的源码,可以看到是一个 Class 类型的数组。
在这里插入图片描述
我们可以导入自己写的类的组件,也可以导入依赖的组件。
在这里插入图片描述
@Import 会调用它们的无参构造方法,给容器中自动创建出这两个类型的组件。

我们来做个简单的测试。由于 Book 类我们定义了两个生成 Bean 的方法,所以可以通过 getBeanNamesForType() 方法来获取容器中 Book 类对应的所有 id。
在这里插入图片描述
可以看到,除了我们定义的 bbb 之外,还有一个就是 Book 的全类名,这就是通过 @Import 注解导入的。下面还有一个 SLF4JBridgeHandler 类的全类名,显然这就是我们通过@Import 注解导入的另一个类。

Ⅲ @Conditional

@Conditional条件装配,意为满足 Conditional指定的条件,则进行组件注入。

比如我们在注入 Book 类的时候,需要注入 Press 类的对象。
在这里插入图片描述
但是,如果 Press 类没有对象被注册到容器中的话,Book 类依旧会被创建。

现在我们希望遵从这个依赖性,当 Press 不存在的时候,也不要对 Book 进行注册,要做到这一点我们就需要 @Conditional 注解。
在这里插入图片描述
Conditional 有许多扩展注解,我标记了两个做个例子, ConditionalOnBean 意味着有这个 Bean 时才进行组件注入,相对应的 ConditionalOnMissingBean 意味着没有这个 Bean 时才进行组件注入。

现在我们希望没有 Press 时就不注入 Book,所以可以使用 ConditionalOnBean
在这里插入图片描述
可以看到,ConditionalOnBean 既可以根据 Bean 的类型,也可以根据 Bean 的名称(也就是 id)。我们根据名称来写。
在这里插入图片描述
我把 PressBean 注解注释掉了,以便我们验证效果。
在这里插入图片描述
可以看到,两个 Bean 都没有注册到容器中。

但是如果我们不加 Conditional 注解的话,再次做一个测试。

在这里插入图片描述
Press 没有被注册的情况下,Book 被成功地注册了。

Ⅳ @ImportResource

在上面我们使用的是配置类的方式类进行组件的注册,那么如果我们有一个 xml 配置文件,需要将里面的组件注册进来,就需要使用 @ImportResource 注解。

比如我现在写一个配置文件。
在这里插入图片描述
如果直接就在容器中查找这两个组件,必然是找不到的。
在这里插入图片描述
现在我们需要使用注解将这个配置文件导入,这样才能将其注册。
在这里插入图片描述

Ⅴ 配置绑定

我们有时会在 properties 文件中配置一些信息,比如数据库连接池之类的,然后 Java 来读取 properties 文件中的内容,并把它封装到 JavaBean 中,以供随时使用,这个过程就是配置绑定。

Spring Boot 为此也提供了很方便的方法。

我先定义一个 Bean,Car,只有两个属性,一个是品牌brand 一个是价格price
在这里插入图片描述
完成基本的 Getter Setter 以及 toString 方法。

接着我们在 properties 配置文件中配置这个类的属性。
在这里插入图片描述

1. @ConfigurationProperties

我们并不需要写复杂的解析配置,只需要在对应的实体类上添加一个注解 @ConfigurationProperties

在这个注解中,我们需要写入一个属性 prefix
在这里插入图片描述
这个意思是我们这个类里的属性,和配置文件中哪个前缀下的所有属性一 一绑定。显然这里我们的前缀就是 mycar
在这里插入图片描述
为了使其生效,我们还需要将该类加到容器中,所以需要添加 @Component 注解。
在这里插入图片描述
要做测试,我们可以将 Car 类作为成员变量然后使用 Autowired 注解自动注入。
在这里插入图片描述
我们来测试一下这个响应,可以看到 Car 类被正确注入了我们配置文件中的数据。
在这里插入图片描述

2. @EnableConfigurationProperties

我们需要在配置类上写一个注解 EnableConfigurationProperties,表示开启属性配置功能。既然我们要开启 Car 类的属性配置,所以就需要将它传进去。
在这里插入图片描述
这个注解除了会开启 Car 的配置绑定功能以外,还会将Car 这个组件自动注册到容器中。

使用这个方法我们就不需要在 Car 类上添加 @Component 注解了,毕竟我们有可能要配置的是第三方的类,我们是不能在别的类上添加代码的。

测试仍然是成功的。
在这里插入图片描述

Ⅵ 其他

@Bean, @Component, @Controller, @Service@Repository 这些注解的用法都和 Spring 5 、 Spring MVC 中的一样,不再赘述。

猜你喜欢

转载自blog.csdn.net/qq_45627684/article/details/114802593
今日推荐