spring boot知识总结

版权声明:未经博主同意,谢绝转载!(请尊重原创,感谢) https://blog.csdn.net/topdeveloperr/article/details/81879734

目录

Spring Boot是什么?

Spring Boot  Starter

约定1:项目结构层面的约定

约定2:springMVC框架层面的约定和定制

约定3:嵌入式web容器层面的约定和定制

Automatically Configuration

关于@SpringBootApplication这个注解的作用,记住下面这张图即可:

@Configuration

@ComponentScan

@EnableAutoConfiguration

自动配置幕后英雄:SpringFactoriesLoader详解

Acutator

spring boot启动过程


Spring Boot是什么?

Spring Boot是为简化Spring MVC/spring的开发而生的项目。主要从以下三个方面:

  1. simplify configuration 简化配置

  2. simplify deployment简化部署

  3. simplify monitor 简化系统监控

spring boot由四个主要的组件组成:

  1. Spring Boot  Starter:

  2. Automatically Configuration.

  3. CLI. Use with groovy.

  4. Actuator

Spring Boot  Starter

spring boot starter起到的作用是,把一些列的依赖结合起来,依赖之间可以像java类继承一样引用对方。这样的好处是解决了依赖之间冲突的问题(这个问题在maven使用过程中非常常见),减少了依赖的数量。

下面是一个spring boot starter web的例子:

在这个时代,使用spring开发的应用大多数都是在使用springMVC开发web应用,为了帮我们快速搭建并开发一个web项目,spring boot为我们提供了spring-boot-starter-web自动配置模块。

只要将spring-boot-starter-web加入项目的maven依赖,我们就得到了一个直接可执行的web应用,在当前项目下运行spring boot:run,就可以直接启动一个使用了嵌入式Tomcat服务的web应用,只不过我们还没有提供任何可以响应web请求的controller,所以当前访问任何的路径都会返回一个spring boot默认提供的错误页面(white label error page). 如果在当前项目下新建一个服务根路径web请求的controller:

@RestController
public class IndexController {
    @RequestMapping("/")
    public String index(){
        return "hello, there";
    }
}

重新运行mvn spring-boot:run并访问http://localhost:8080,错误页面将被controller返回的消息所替代。至此,一个简单的web应用就已经这样完成了。但是,毫无疑问背后的潜规则(约定)是我们必须去了解的。

约定1:项目结构层面的约定

与传统打包为war包的java web应用的差异在于,静态文件和页面模板的存放位置变了,原来是放在src/main/webapp目录下的一系列资源,现在都统一放在了src/main/resources下。

约定2:springMVC框架层面的约定和定制

spring-boot-starter-web默认为我们配置了一些springMVC必要组件

  1. ViewResolver
  2. Converter,Formatter等bean注册到IoC
  3. HttpMessageConverter
  4. MessageCodesResolver

当然,我们完全可以自己配置这些东西,而不用它提供的配置。

约定3:嵌入式web容器层面的约定和定制

  1. 默认使用嵌入式tomcat作为web容器对外提供http服务,默认使用8080端口对外监听和提供服务
  2. 假设不行使用签署tomcat,可引入spring-boot-starter-jetty或spring-boot-starter-undertow作為替代
  3. 假设不想使用8080作为默认端口,可以更改配置项server.port使用自己指定的端口号,如:server.port = 9000

Automatically Configuration

自动配置的主要职责是:减少spring的配置。

自动配置是什么,用一个例子比较好说明。当我们把spring-boot-starter-web加入到项目的maven依赖里以后,它就会自动的添加spring mvc的相关依赖,如果spring mvc相关的配置在classpath里面被scan到,它就会自动的将相关的bean加到IoC容器里面(messageConvert等)。spring启动的时候会扫描classpath并且去找META-INF/spring.factories这个文件,然后去加载configuration. 这个文件的格式是 key = value的格式,并且key和value都必须是java 类的全限定名(Fully qualified), 比如:

   exmaple.MyService = example.MyServiceImpl

如果我们使用了注解@EnableAutoConfiguration,它会去加载,实例化所有加了@Configuration的注解的类到IoC容器里去(ApplicationContext),通常,这个注解会用在主类里边,并且主类一般是在开发包的最顶部,因此它就可以扫描到所有的类。

@EnableAutoConfiguration这个注解的示意图如下:

@ComponentScan:

会自动扫描包路径下面的所有@Controller、@Service、@Repository、@Component 的类。

 basePackages指定扫描的包,includeFilters包含那些过滤,excludeFilters不包含那些过滤,useDefaultFilters默认的过滤规则是开启的,如果我们要自定义的话是要关闭的

@Configuration

把一个类标记为IoC容器的一个bean

关于@SpringBootApplication这个注解

这个注解由下面几个注解组成:

@Configuration

它就是JavaConfig形式的Spring Ioc容器的配置类使用的那个@Configuration.

这里的启动类标注了@Configuration之后,本身其实也是一个IoC容器的配置类。

任何一个标注了@Configuration的Java类定义都是一个JavaConfig配置类。

@SpringBootApplication
public class Application {

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

	

这个springBoot启动类等价于下面的写法:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class AppConfiguration{
    @Bean
    public Controller controller(){
        return new Controller();
    }
}

@SpringBootApplication
public class Application {

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

经过这样的改造之后,就很明白了,启动类就是一个普通的main函数启动类,没有什么特别之处,在main 里面调用了一个方法而已。

而由@Configuration修饰的AppConfiguration类定义就是一个普通的javaConfig形式的IoC容器配置类而已。

@ComponentScan

@ComponentScan这个注解在Spring中很重要,它对应XML配置中的元素,@ComponentScan的功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。

我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。

p.s. 所以SpringBoot的启动类最好是放在root package下,因为默认不指定basePackages

@EnableAutoConfiguration

@EnableAutoConfiguration是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器,仅此而已。

它本事也是一个复合的注解,它的实现如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    ...
}

最关键的要属@Import(EnableAutoConfigurationImportSelector.class),借助EnableAutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器.

借助于Spring框架原有的一个工具类:SpringFactoriesLoader的支持,@EnableAutoConfiguration可以智能的自动配置功效才得以大功告成.

自动配置幕后英雄:SpringFactoriesLoader详解

SpringFactoriesLoader属于Spring框架私有的一种扩展方案,其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。

配合@EnableAutoConfiguration使用的话,它更多是提供一种配置查找的功能支持,即根据@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为查找的Key,获取对应的一组@Configuration类.

以下是从springBoot的:spring-boot-autoconfigure依赖包中的截图:

@EnableAutoConfiguration自动配置的魔法就是:从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableautoConfiguration对应的配置项通过反射(Java Refletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器

在我们启动spring boot的app时会调用一个SpringBootApplication的run方法。这个方法在执行过程中会去主动初始化需要用到的bean。其重要实现如下:

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
        if (result != null) {
            return result;
        } else {
            try {
                Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
                LinkedMultiValueMap result = new LinkedMultiValueMap();

                while(urls.hasMoreElements()) {
                    URL url = (URL)urls.nextElement();
                    UrlResource resource = new UrlResource(url);
                    Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                    Iterator var6 = properties.entrySet().iterator();

                    while(var6.hasNext()) {
                        Entry<?, ?> entry = (Entry)var6.next();
                        List<String> factoryClassNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray((String)entry.getValue()));
                        result.addAll((String)entry.getKey(), factoryClassNames);
                    }
                }

                cache.put(classLoader, result);
                return result;
            } catch (IOException var9) {
                throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var9);
            }
        }
    }

可以看到,是从一个名字(变量FACTORIES_RESOURCE_LOCATION)叫spring.factories的资源文件中,读取所有的配置信息存放在了一个LinkedMultiValueMap类型的局部变量result当中。

Acutator

spring提供了actutator用于帮助我们监控服务的各种状态:

路径 作用

info

know the service situation
error  
autoconfig list config decisions
beans List  all the config beans
dump List application’s thread information
/env/{name} list all the environment variables
health  
info  
/metrics/{name} list the realated index
shutdown shut down the service
trace list the recent quest metadata,include request and response header
configprops list all the  @ConfigurationProperties

spring boot启动过程

spring boot项目的启动过程大致如下图:

猜你喜欢

转载自blog.csdn.net/topdeveloperr/article/details/81879734