引言
搭建一个J2EE的web项目,要经过一系列步骤,如配置maven,集成jar,配置xml代码,然后开发代码,打包, 部署,测试等,Spring意识到这些很繁琐,且机械化,有共通性,可以实现自动化,因此提出直接一站式、整体解决方案,简化快速地开发应用。
网址
https://spring.io/projects/spring-boot
https://spring.io/guides
本人学习教程也附录上 :http://www.chilangedu.com/course/1489582623.html#0
版本说明 springboot 1.5.9
1、Maven设置
参考
https://www.jianshu.com/p/d9b3843810ec
https://www.jianshu.com/p/6654e9fec93b
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
helloworld工程(IDEA工具开发)
1、pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>myproject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
编写Application Controller 代码
略
打包
在pom文件中添加以下插件
<!-- 该插件可以将应用打包成一个可以执行的jar包-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
部署
java -jar xxx.jar
springboot 场景启动器 starter
1、pom中的父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
他的父项目是
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
这里面有各种依赖,自动帮我们进行jar包引用与版本仲裁
1、springboot的场景依赖管理
开发什么功能所对应的依赖springboot帮我们管理好了(由版本仲裁来导入)
导入的依赖
what:spring-boot-starter-web 是什么?
是web应用场景对应的pom,文件名如 spring-boot-starter-web-1.5.9.RELEASE.pom。
其中包含了常用web相关的组件,如tomcat,jackson,springmvc等。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<artifactId>spring-boot-starter-web</artifactId>
<name>Spring Boot Web Starter</name>
<description>Starter for building web, including RESTful, applications using Spring
MVC. Uses Tomcat as the default embedded container</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
</dependencies>
</project>
更多的依赖场景参考官网
https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/
13.5 Starters中的应用场景列表,以mail为例
只需要引用spring-boot-starter-mail即可引用mail开发需要的pom,mail的pom如下
https://github.com/spring-projects/spring-boot/blob/v1.5.9.RELEASE/spring-boot-starters/spring-boot-starter-mail/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<artifactId>spring-boot-starter-mail</artifactId>
<name>Spring Boot Mail Starter</name>
<description>Starter for using Java Mail and Spring Framework's email sending
support</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
</dependencies>
</project>
主程序类,主入口类
SpringBootApplication
/**
* @SpringBootApplication 应用主程序
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
// Spring应用启动
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
@SpringBootApplication
在某个类上标注,说明这个类就是SpringBoot的主配置类
SpringBoot就该运行在这个类的main方法来启动SpringBoot应用
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 {
@AliasFor(
annotation = EnableAutoConfiguration.class,
attribute = "exclude"
)
@SpringBootConfiguration 这个是SpringBoot的配置类(SpringBoot注解)
@Configuration 配置类上来标注这个注解(spring注解)
配置类是容器中的一个组件,@Component
@EnableAutoConfiguration 开启SpringBoot的自动配置功能
enable 开启,auto 自动
原理:
点击EnableAutoConfiguration查看源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
1、@AutoConfigurationPackage自动配置包的内部信息
@AutoConfigurationPackage
@Import({EnableAutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
}
Registrar的信息
@Order(-2147483648)
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
Registrar() {
}
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
}
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new AutoConfigurationPackages.PackageImport(metadata));
}
}
metadata 是元数据
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器中。
也就是说如果不是在主配置类下面,而是跨包的类的话,就无法扫描到。则无法自动配置
给容器中导入组件
2、@Import({EnableAutoConfigurationImportSelector.class})
EnableAutoConfigurationImportSelector 给容器中导入那些组件的选择器
将所有需要导入的组件以全类名的方式返回(xxxAutoConfiguration)就是给容器中的导入这个场景所需要的所有组件,并配置好这些组件。
what?导入那些组件呢?
@Import({EnableAutoConfigurationImportSelector.class})
点进去查看
public class EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector
所以查看父类AutoConfigurationImportSelector的方法,其中有个selectImports方法
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
try {
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
configurations = this.removeDuplicates(configurations);
configurations = this.sort(configurations, autoConfigurationMetadata);
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.filter(configurations, autoConfigurationMetadata);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return (String[])configurations.toArray(new String[configurations.size()]);
} catch (IOException var6) {
throw new IllegalStateException(var6);
}
}
}
通过在通过返回的configurations数组可以知晓和web相关的有96个组件
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
启动项目后,在这个getCandidateConfigurations处打断点,可以看到如下configurations,这些就是spring获取到的自动配置类,然后springboot就帮我们自动导入了,不需要我们手写了,其中包含了Aop配置,Rabbit,Cache,MVC等配置类。
如何获取到这些类呢?
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;
}
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
ArrayList result = new ArrayList();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames = properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
} catch (IOException var8) {
throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + "META-INF/spring.factories" + "]", var8);
}
}
总之就是
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, classLoader );
然后loadFactoryNames中有扫描工厂路径的URL文件配置
Enumeration urls = classLoader != null ? classLoader.getResources(“META-INF/spring.factories”) : ClassLoader.getSystemResources(“META-INF/spring.factories”);
SpringBoot在启动的时候,从类的路径下的META-INF/spring.factories 获取要配置的EnableAutoConfiguration指定的类名,将这些类名值作为自动配置类导入到容器中,自动配置了就生效了,从而帮我们进行配置工作。以前我们自己配置的东西,Spring都在这里面帮我们做了,如web中MVC需要视图解析器ViewResolver。
调用的方法在如下jar中可以看到C:\Users\Administrator.m2\repository\org\springframework\boot\spring-boot-autoconfigure\1.5.9.RELEASE\spring-boot-autoconfigure-1.5.9.RELEASE.jar
知道了这个后,如果后期针对个别项目需要调整,可以在这个包中修改调整。
SpringBoot_入门-使用向导快速创建Spring Boot应用
new Project>Spring Initializr
参考博客 https://blog.youkuaiyun.com/qingtian_1993/article/details/79774698