SpringBoot——@SpringBootApplication注解分析

农村四月闲人少,勤学苦攻把名扬。这篇文章主要讲述SpringBoot——@SpringBootApplication注解分析相关的知识,希望能为你提供帮助。
Spring boot简介

  • Spring Boot是伴随着Spring4.0  产生的,是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。
  • Spring Boot让我们的Spring应用变得更轻量化。比如:你可以仅仅依靠一个java类来运行Spring引用。你也可以打包你的应用为jar并通过使用java – jar来运行你的Spring Web应用。
  • Spring Boot的主要优点:
    为所有Spring开发者更快的入门
    开箱即用,提供各种默认配置来简化项目配置
    内嵌式容器简化web项目
    没有冗余代码生成和xml配置的要求
    尽可能的根据项目依赖来自动配置Spring框架。
    提供可以直接在生产环境中使用的功能,如性能指标,应用信息和应用健康检查。
  • Spring Boot的缺点
    依赖太多,随便的一个Spring Boot应用都有好几十M
    缺少服务的注册和发现等解决方案,可以结合springcloud的组件使用。
    缺少监控集成方案、安全管理方案(有但简单,满足不了生产的指标)
首先我们分析的就是入口类Application的启动注解@SpringBootApplication,进入源码:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { .... }

发现@SpringBootApplication是一个复合注解,包括@ComponentScan,和@SpringBootConfiguration@EnableAutoConfiguration
  • @SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到srping容器中,并且实例名就是方法名。
  • @EnableAutoConfiguration的作用启动自动的配置,@EnableAutoConfiguration注解的意思就是Springboot根据你添加的jar包来配置你项目的默认配置,比如根据spring-boot-starter-web  ,来判断你的项目是否需要添加了webmvctomcat,就会自动的帮你配置web项目中所需要的默认配置。在下面博客会具体分析这个注解,快速入门的demo实际没有用到该注解。
  • @ComponentScan,扫描当前包及其子包下被@Component@Controller@Service@Repository注解标记的类并纳入到spring容器中进行管理。是以前的< context:component-scan> (以前使用在xml中使用的标签,用来扫描包配置的平行支持)。所以本demo中的User为何会被spring容器管理。
根据上面的理解,上面的入口类Application,我们可以使用:
package com.zhihao.miao; import com.zhihao.miao.bean.User; import org.springframework.boot.SpringApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import java.util.Map; @ComponentScan public class Application {@Bean public Runnable createRunnable(){ return () -> System.out.println("spring boot is running"); }public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Application.class,args); context.getBean(Runnable.class).run(); } }

使用@ComponentScan注解代替@SpringBootApplication注解,也可以正常运行程序。原因是@SpringBootApplication中包含@ComponentScan,并且springboot会将入口类看作是一个@SpringBootConfiguration标记的配置类,所以定义在入口类Application中的Runnable也可以纳入到容器管理。
 
SpringBootApplication参数详解
SpringBoot——@SpringBootApplication注解分析

文章图片

【SpringBoot——@SpringBootApplication注解分析】 
 
             
  • Class< ?> [] exclude() default {}:
    根据class来排除,排除特定的类加入spring容器,传入参数value类型是class类型。
  • String[] excludeName() default {}:
    根据class name来排除,排除特定的类加入spring容器,传入参数value类型是class的全类名字符串数组。
  • String[] scanBasePackages() default {}:
    指定扫描包,参数是包名的字符串数组。
  • Class< ?> [] scanBasePackageClasses() default {}:
    扫描特定的包,参数类似是Class类型数组。
@SpringBootApplication只会扫描@SpringBootApplication注解标记类包下及其子包的类(特定注解标记,比如说@Controller,@Service,@Component,@Configuration和@Bean注解等等)纳入到spring容器,如果我们定义的Bean不在@SpringBootApplication注解标记类相同包下及其子包的类,所以需要我们去配置一下扫包路径。
修改启动类,@SpringBootApplication(scanBasePackages = "com.xxx.xxx"),指定扫描路径:
import com.zhihao.miao.beans.Cat; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication(scanBasePackages = "com.xxx.xxx") public class Application {public static void main(String[] args) { ConfigurableApplicationContext context =SpringApplication.run(Application.class,args); } }

当然使用@SpringBootApplication(scanBasePackageClasses = MyConfig.class),指定scanBasePackageClasses参数的value值是你需要扫描的类也可以,结果一样,不过如果多个配置类不在当前包及其子包下,则需要指定多个。
exclude或excludeName在上面的列子的相同包下(com.xxx.xxx)配置的bean,都会纳入到spring容器中(@Component),我们知道@SpringBootApplication注解会扫描当前包及其子包,如果我们需要将其排除在spring容器中,如何操作?
可以使用@SpringBootApplication的另外二个参数(exclude或excludeName)
然后修改@SpringBootApplication配置,
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; @SpringBootApplication(exclude = People.class) public class Application {public static void main(String[] args) { ConfigurableApplicationContext context =SpringApplication.run(Application.class,args); People people = context.getBean(People.class); System.out.println(people); } }

很明显启动报错。使用@excludeName注解也可以。如下,
@SpringBootApplication(excludeName = {"com.xxx.xxx.People"})
  • @SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到srping容器中,并且实例名就是方法名。
  • @EnableAutoConfiguration的作用启动自动的配置,@EnableAutoConfiguration注解的意思就是Springboot根据你添加的jar包来配置你项目的默认配置,比如根据spring-boot-starter-web  ,来判断你的项目是否需要添加了webmvctomcat,就会自动的帮你配置web项目中所需要的默认配置。在下面博客会具体分析这个注解,快速入门的demo实际没有用到该注解。
  • @ComponentScan,扫描当前包及其子包下被@Component@Controller@Service@Repository注解标记的类并纳入到spring容器中进行管理。是以前的< context:component-scan> (以前使用在xml中使用的标签,用来扫描包配置的平行支持)。所以本demo中的User为何会被spring容器管理。

    推荐阅读