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);
        }
    }
}

启动即可


 
image.png

在上图中我们可以看到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  阅读(244)  评论(0编辑  收藏  举报