点击上方☝SpringForAll社区 轻松关注!
及时获取有趣有料的技术文章本文来源:http://rrd.me/g8Bce
最近在项目中使用 Spring Boot,对它的简单易用印象很深刻。Spring Boot 最大的特点是它大大简化了传统 Spring 项目的配置,使用 Spring Boot 开发 Web 项目,几乎没有任何的 xml 配置。而且它最方便的地方在于它内嵌了 Servlet 容器(可以自己选择 Tomcat、Jetty 或者 Undertow),这样我们就不需要以 war 包来部署项目,直接使用 java -jar hello.jar
就可以运行一个 Web 项目。
我们以 Maven 项目为例,Spring Boot 除了支持 Maven,还支持 Gradle 项目。一个最简单的 Spring Boot Web 项目只有 3 个文件(其实如果想要更简单一点,入口和控制器类甚至可以写在同一个文件中)。首先是一个入口文件:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
然后再写一个控制器类:
@RestController
public class HelloController {
@RequestMapping("/")
public String index() {
return "Hello World!";
}
}
最后是这个项目的 POM(Project Object Model,项目对象模型) 文件:
<?xml version="1.0" encoding="UTF-8"?>
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">
4.0.0
com.stonie
spring-boot-sample
1.0-SNAPSHOT
org.springframework.bootspring-boot-starter-parent2.0.2.RELEASE
org.springframework.bootspring-boot-starter-web
1.8
org.springframework.bootspring-boot-maven-plugin
在新建 Spring Boot 项目的时候要注意一点,入口类必须放在某个包下面,而不能放在默认包(也就是说不能直接放在 srcmainjava 目录下),否则会导致项目启动失败(其实原因很简单,因为 Spring Boot 通过 @ComponentScan 来扫描 Bean,如果入口类放在默认包下,也就意味着 Spring Boot 要扫描所有 jar 包中的所有的类):
** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.
至此,我们就写好了一个 Spring Boot 项目,完整的源码可以参考 这里。从代码上看项目非常简单,但是这里有很多值得我们学习的地方。
一、从 SpringBootApplication 注解看 Spring Boot 自动配置原理
Spring Boot 项目通常都有一个入口类,入口类中的 main
方法和标准的 Java 应用入口方法是一样的,在上面的例子中,这个 main
方法中只有一行代码:SpringApplication.run()
,这是一个静态方法,用于启动整个 Spring Boot 项目。和其他 Java 程序不一样的是,入口类上多了一个 @SpringBootApplication
注解,这是非常重要的一个注解,它由多个注解组合而成,包括了:@SpringBootConfiguration
、@EnableAutoConfiguration
、@ComponentScan
和其他一些注解。Spring Boot 是如何做到不需要任何配置文件的,看名字也可以猜出来,其秘密就在于 @EnableAutoConfiguration
这个注解实现了自动配置。这个注解的实现如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class>[] exclude() default {};
String[] excludeName() default {};
}
其中最为重要的一行代码为:@Import({AutoConfigurationImportSelector.class})
,其中 @Import
是 Spring 提供的一个注解,可以导入配置类或者 Bean 到当前类中。AutoConfigurationImportSelector
类的实现比较复杂,简单来说就是扫描所有 jar 包中的 META-INF/spring-factories
文件,这个文件中声明了有哪些自动配置。我们可以打开 spring-boot-autoconfigure.jar 文件,这里就有这个文件,其中定义了一个属性 org.springframework.boot.autoconfigure.EnableAutoConfiguration
如下所示(有删减):
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\