SpringBoot 启动类 @SpringBootApplication 注解

SpringBootApplication是一个复合注解,包括@ComponentScan,和@SpringBootConfiguration,@EnableAutoConfiguration。

1 @SpringBootConfiguration

SpringBootConfiguration注解是spring boot中的配置注解类。它继承自spring中的Configuration配置注解类。

1.1 @Configuration注解

Configuration是spring的配置注解类,用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

1.1.1使用
@SpringBootConfiguration
@ComponentScan("com.example.springbootdemo") //
public class Configuration {
    @Bean(initMethod = "initMethod")
    public Piano piano(){
        return new Piano();
    }

    @Bean
    public Harmonica harmonica(){
        piano();//测试SpringBootConfiguration类对BEAN只实例化一次
        return new Harmonica();
    }
}

启动类:

public class SpringbootDemoApplication {

//    public static void main(String[] args) {
//        SpringApplication.run(SpringbootDemoApplication.class, args);
//    }
    public static void main(String[] args) {

        ApplicationContext annotationContext = new AnnotationConfigApplicationContext(Configuration.class);
        ApplicationContext annotationContext = new AnnotationConfigApplicationContext(Configuration.class);
        System.out.println(annotationContext.getBean(Piano.class));
        System.out.println(annotationContext.getBean(Piano.class));
    }
}

执行结果:
image.png

从打印结果来看,Piano类只被实例化了一次。现将Confinguration类的@SpringBootConfiguration注销,再执行代码,运行结果如下:
image.png

从运行结果看,Piano类被实例化了两次。

结论:@SpringBootConfiguration注解实例化为单例模式

1.1.2 Configuration注释的类会被CGLIB代理

验证过程:
Configuraion未加@Configuration注解

//@SpringBootConfiguration
@ComponentScan("com.example.springbootdemo") //
public class Configuration {
    @Bean(initMethod = "initMethod")
    public Piano piano(){
        return new Piano();
    }

    @Bean
    public Harmonica harmonica(){
        piano();//测试SpringBootConfiguration类对BEAN只实例化一次
        return new Harmonica();
    }
}

main方法

    public static void main(String[] args) {

        ApplicationContext annotationContext = new AnnotationConfigApplicationContext(Configuration.class);
        System.out.println(annotationContext.getBean(Configuration.class));
//        System.out.println(annotationContext.getBean(Piano.class));
//        System.out.println(annotationContext.getBean(Piano.class));

    }

执行后返回结果:
image.png

Configuration加上@Configuration注解

@SpringBootConfiguration
//@ComponentScan("com.example.springbootdemo") //
public class Configuration {
    @Bean(initMethod = "initMethod")
    public Piano piano(){
        return new Piano();
    }

    @Bean
    public Harmonica harmonica(){
        piano();//测试SpringBootConfiguration类对BEAN只实例化一次
        return new Harmonica();
    }
}

再次执行main方法,返回结果如下:
image.png

结论:通过@Configuration注解的类会被CGLIB代理

注意:@Configuration注解的配置类有如下要求:
1.@Configuration不可以是final类型;
2.@Configuration不可以是匿名类;
3.嵌套的configuration必须是静态类。

1.1.2 源码分析

在Spring 容器创建过程时,我们知道容器默认会加载一些后置处理器PostPRocessor,其中 ConfigurationClassPostProcessor这个后置处理器专门处理带有@Configuration注解的类,ConfigurationClassPostProcessor后置处理实现了BeanDefinitionRegistryPostProcessor接口和PriorityOrdered接口,所以会在容器初始化refres()方法中执行后置处理器时优先执行,主要负责解析所有@Configuration标签类,并将Bean定义注册到容器中。

2 @EnableAutoConfiguration

你可能感兴趣的:(SpringBoot 启动类 @SpringBootApplication 注解)