Configuration注解(配置注解)
场景:
现在有两个类,想办法把这两个类加入到组件之中
传统方式:写xml文件,写bean标签
现在的方式:直接写配置类,把之前xml文件内的东西写在类里
(1)创建配置类==创建xml文件
(2)对向进行容器实例化==写bean标签
现在我们只需要写普通的类,最后返回new一个我们想要的对象,需要属性的直接有参构造和无参构造即可。
最后再在类上加上@Bean注解
加了注解之后这个类就会,以方法名作为组件的id,返回类型为组件类型,返回的值就是组件在容器中的实例
package com.LALALA.boot.config;
import com.LALALA.boot.bean.Pet;
import com.LALALA.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration//告诉springboot这是一个配置类 等同于之前写的xml配置文件
public class MyConfig {
@Bean//以方法名作为组件的id,返回类型为组件类型,返回的值就是组件在容器中的实例
public User user01(){
return new User("zhangsan",18);
}
@Bean
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
因为之前我们在主程序中已经返回了容器组件,并且打印了组件名称,现在我们执行看看有么有user01和tomcatPet
是有的,但是如果我们想修改容器中组件的名称但是不修改方法名怎么办?
@Bean(“自己想加的名字”)即可,例如
配置类的特点
那么我们容器中的组件是单实例的还是多实例的呢?
测试:
事实证明,我们两次获取的组件都是同一个组件,默认是单实例的
那么我们的配置类实际上是不是也是一个组件呢?
测试:
配置类本身也是组件
既然我们的配置类也是组件,可不可以调用配置类组件里面创建组件到容器的方法,如果调用了两次,创建的还是同一个组件吗?
测试:
可以调用,而且是同一个
特点总结:
代理Bean方法
如歌把这个属性改为flase会怎么样?
我们现在的user01和user02不是同一份对象了
注意:为什么上面的判断是否是一个组件的结果还是true
因为组件是工具,用组件生成出来的是对象,本质不同 ,代理模式变了,但是不改变工具还是同一把的事实
这就是轻量级模式和重量级模式
那么轻量级模式可以解决什么问题?
组建依赖
什么是组件依赖?
譬如说,现在我们的user对象有一个属性为pet宠物,这样子在user组件创建的时候就要设置user组件里面的pet属性,也就是说要使用pet对象,此时user组件依赖于pet组件。
@Configuration(proxyBeanMethods = true)//告诉springboot这是一个配置类 等同于之前写的xml配置文件
public class MyConfig {
@Bean//以方法名作为组件的id,返回类型为组件类型,返回的值就是组件在容器中的实例
public User user01(){
User zhangSan = new User("zhangsan",18);
zhangSan.setPet(tomcatPet());
return zhangSan;
}
@Bean
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
测试
User user03 = run.getBean("user01", User.class);
Pet pet = run.getBean("tomcatPet", Pet.class);
//对比组件创造出来的pet对象和user03里的pet对象是不是同一个
System.out.println(user03.getPet()==pet);
是同一个
如果把代理Bean方法改为flase,此时我们再用tomcatPet组件创建pet对象,此时就和一开始user里就创建的pet对象属性不是同一个了,相当于组件又新创建了一个pet对象
为什么要有轻量级和重量级模式的区分?
如果此时我们的应用中有组建依赖,就设置重量级
如果没有组件依赖,就设置轻量级,这样程序启动的更快
@Import(导入组件注解)
作用:给容器中导入自己设定的组件(可以是自己写的,也可以是jar包里面的)
用法:加在任何一个组件上面,属性填写想添加的组件类
例如:
测试看看容器中有没有这两个组件
成功
@Conditional(条件装配注解)
作用
第一个是当容器中存在我们指定的某些组件的时候才做出某些事
第一个是当容器中没有存在我们指定的某些组件的时候才做出某些事
以第一个为例子
如果此时我们把pet的bean注解去掉,此时容器中就不会有tomcatPet组件了,但是user01组件还是正常存在
//测试此时容器中有没有tomcatPet组件
boolean tomcatPet = run.containsBean("tomcatPet");
System.out.println("tom:::"+tomcatPet);
//测试此时容器中有没有User01组件
boolean user01 = run.containsBean("user01");
System.out.println("user01:::"+user01);
但是此时我们的user01组件是依赖于toncatPet组件的,我们现在想,如果容器里有 toncatPet组件组件的时候才创建user01组件——使用@Conditional注解
此时user01组件也不会被创建了
这个注解甚至可以直接加在配置类上
但是此时tomcatPet组件还没有,所以这两个组件都不会被创建
@ImportResource(原生配置文件引入注解)
使用场景:如果我们不得不使用第三方的xml文件,但是自己有写了一些组件,可以用这个组件把两者结合
例如现在有xml文件:
![](https://img-blog.csdnimg.cn/072c70e02d7244acb6cf2e05df3a2ecc.png)
现在看看容器中有没有这两个组件
但是只需要在配置类上加上注解并且指明xml文件的位置即可
可以了
@ConfigurationProperties(配置绑定注解)
使用场景:现在我们的配置文件里有几千行配置,但是现在我们想修改数据库连接的配置,找起来很麻烦,就可以使用这个注解
现在有个类,把它的属性绑定到配置文件当中
使用注解——该注解内有个属性为prefix(前缀),意思是在这个属性内填写什么,就会注入配置文件中前缀和我们设定的相同的同名属性
但是现在报错,我们把car这个类加入到容器中,让它变成一个组件就好了
测试:
成功
第二种方法
使用@EnableConfigurationProperties注解
这个注解有两个功能
用法:写在配置类上,属性填写想要绑定配置文件的类
这样子就不用在car这个类上写 注解,把car加入到容器内中了,这个注解会帮我们做好
这样的好处是,如果car是第三方提供給我们的类,我们可以尽量的对这个类不改动
测试成功