zoukankan      html  css  js  c++  java
  • @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参数详解

    • 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"})

    参考文档:
    Springboot1.5.4官方文档

  • 相关阅读:
    Using Resource File on DotNet
    C++/CLI VS CSharp
    JIT VS NGen
    [Tip: disable vc intellisense]VS2008 VC Intelisense issue
    UVa 10891 Game of Sum(经典博弈区间DP)
    UVa 10723 Cyborg Genes(LCS变种)
    UVa 607 Scheduling Lectures(简单DP)
    UVa 10401 Injured Queen Problem(简单DP)
    UVa 10313 Pay the Price(类似数字分解DP)
    UVa 10635 Prince and Princess(LCS N*logN)
  • 原文地址:https://www.cnblogs.com/duanxz/p/3756364.html
Copyright © 2011-2022 走看看