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引入方式



    
    
        
    
    

但是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模式

你可能感兴趣的:(springboot注解-@Configuration)