springboot注解-@Configuration
基本使用
@Configuration是springboot中常用的注解,它的意思是声明一个类为配置类(相当于之前我们经常使用xml的形式进行一些组件的配置,现在不过是换了个方式)并将其添加到IOC容器中。
在springmvc中,如果我们想要引入一个bean,我们通常添加一个配置文件。
在此之前,我们需要先声明一个bean
public class Cat {
public String name;
public Cat() {
}
public Cat(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
springmvc引入方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="tom" class="per.wqy.bean.Cat">
<property name="name" value="tom01"></property>
</bean>
</beans>
但是springboot一般不使用这种方式,SpringBoot使用配置类的方式
@Configuration // 告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
@Bean //给容器中添加组件。以方法名作为组件id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
public Cat tom(){
return new Cat("tom01");
}
}
添加好配置类之后,我们可以在主程序中添加查看组件的代码
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 1、 返回IOC容器
ConfigurableApplicationContext context = SpringApplication.run(Application.class);
// 2、获取容器中组件的名称并打印
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
启动即可
在上图中我们可以看到myConfig也被注册到了IOC容器中,这其实也说明了配置类本身也是组件。
@Configuration的模式
再看注解@Configuration
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;
}
它有一个属性proxyBeanMethods默认为true,这个是干嘛的呢?
举一个简单的例子,我们修改一下启动类的代码
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
String[] names = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
Cat cat = (Cat) context.getBean("tom");
System.out.println(cat);
MyConfig myConfig = context.getBean(MyConfig.class);
// 如果使用@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中
Cat tom1 = myConfig.tom();
Cat tom2 = myConfig.tom();
System.out.println("组件:"+(tom1==tom2));
}
}
最终结果为:组件:true
就像代码中注释说的那样,如果使用@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中,如果是在容器中的就直接取出,保证组件是单例的,否则直接创建一个新的对象。
这里引申出@Configuration得两种模式
1、Full模式proxyBeanMethods = true
2、Lite模式proxyBeanMethods = false
Full模式保证了组件是单例的,所以当被其他组件引用时,就一定能确定就是该组件被引入了,但是每次实例化一个组件时,都得去IOC容器里查看是否该组件已经存在。所以程序在启动时就会变慢。
综上:
配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,使用Full模式
作者:Qiansion齐木楠雄
链接:https://www.jianshu.com/p/6408efea50fa
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted on 2022-06-08 20:05 1450811640 阅读(262) 评论(0) 编辑 收藏 举报