您的位置:首页 > 编程语言 > Java开发

SpringBoot启动及自动配置原理(注解)分析

2018-03-28 17:50 656 查看

一、SpringBoot入门

1、SpringBoot简介

简化spring的开发,约定大于配置,是spring技术栈的一个大整合,是J2EE开发的一站式解决方案。

是目前互联网公司微服务架构的首选,微服务即一个应用应该是一组小型服务,通过http的方式互通,每一个功能元素最终都是一个可独立替换和独立升级的软件单元。

2、pom.xm文件分析(搭建springhelloworld工程略)

<build>
<finalName>sales-car-source</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


这个插件,可以将应用打包成一个可执行的jar包,可以使用java -jar运行jar包;

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.7.RELEASE</version>
</parent>


它的父项目是

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.7.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>


在spring-boot-dependencies里,有管理所有依赖的版本

<properties>
<!-- Dependency versions -->
<activemq.version>5.14.5</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.56</appengine-sdk.version>
<artemis.version>1.5.5</artemis.version>
<aspectj.version>1.8.10</aspectj.version>
<assertj.version>2.6.0</assertj.version>
<atomikos.version>3.9.3</atomikos.version>
<bitronix.version>2.1.4</bitronix.version>
...
</properties>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
配置处理器,配置文件提示功能


Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter,相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器(如redis,mq)等

3、注解分析

@SpringBootApplication:

Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

@Configuration:

配置类上来标注这个注解;配置类相当于 配置文件;配置类也是容器中的一个组件;@Component

@EnableAutoConfiguration:

开启自动配置功能;以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {


@AutoConfigurationPackage:自动配置包

@Import(AutoConfigurationPackages.Registrar.class):

Spring的底层注解@Import,给容器中导入一个组件;导入的组件由

AutoConfigurationPackages.Registrar.class;

将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;

@Import(EnableAutoConfigurationImportSelector.class);

给容器中导入组件?

EnableAutoConfigurationImportSelector:导入哪些组件的选择器;

将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;

会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,

并配置好这些组件;

有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;<
4000
/p>

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
Assert.notEmpty(configurations,
"No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}


继续分析

Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");


在spring的自动配置的jar里,存在META-INF/spring.factories文件,里面包括了所有spring提供的自动配置。

org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\


我们再拿DataSourceAutoConfiguration分析

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {


核心的就是@EnableConfigurationProperties(DataSourceProperties.class)这个自动配置属性的注解,里面定义了DataSource的属性

@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties
implements BeanClassLoaderAware, EnvironmentAware, InitializingBean {

private ClassLoader classLoader;

private Environment environment;

/**
* Name of the datasource.
*/
private String name = "testdb";

/**
* Generate a random datasource name.
*/
private boolean generateUniqueName;

/**
* Fully qualified name of the connection pool implementation to use. By default, it
* is auto-detected from the classpath.
*/
private Class<? extends DataSource> type;

/**
* Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
*/
private String driverClassName;

/**
* JDBC url of the database.
*/
private String url;

/**
* Login user of the database.
*/
private String username;

/**
* Login password of the database.
*/
private String password;
....


在DataSourceAutoConfiguration里有

@Bean
@ConditionalOnMissingBean
public DataSourceInitializer dataSourceInitializer(DataSourceProperties properties,
ApplicationContext applicationContext) {
return new DataSourceInitializer(properties, applicationContext);
}


@ConditionalOnMissingBean 在没有这个bean的时候我们,执行这个方法,注入DataSourceProperties ,而这个DataSourceProperties 的属性可以通过spring的核心配置文件application.yml文件配置,配置的内容前缀是在属性类上的注解@ConfigurationProperties(prefix = “spring.datasource”)决定定的。

精髓:

1)、SpringBoot启动会加载大量的自动配置类

2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;

3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)

4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;

@ConfigurationProperties

将配置文件中配置的每一个属性的值,映射到这个组件中

@ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;

prefix = “person”:配置文件中哪个下面的所有属性进行一一映射

只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;

@ConfigurationProperties(prefix = “spring.datasource”)默认从全局配置文件中获取值;

@ImportResource:

导入Spring的配置文件,让配置文件里面的内容生效;

Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;

想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类

@ImportResource(locations = {"classpath:beans.xml"})
导入Spring的配置文件让其生效
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: