# 启动原理解析
我们开发一个Spring Boot项目,都会用到如下的启动类
@SpringBootApplication
public class Application {
public static void main(String[] args){
SpringApplication.run(Application.class, args)
}
}
2
3
4
5
6
从上面代码可以看出,Annotation定义(@SpringBootApplication)和类定义(SpringApplication)最为重要
# @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 {
...
}
2
3
4
5
6
7
8
9
10
11
12
虽然定义了多个注解进行原信息标注,但实际上重要的只有三个:
- @Configuration
- @EnableAutoConfiguration
- @ComponentScan
所以,如果我们使用这三个注解代替SpringBootApplication,整个SpringBoot仍然可以正常运行。
# @Configuration
这里的@Configuration对我们来说并不陌生,它是JavaConfig形式的Spring Ioc容器的配置类使用的@Configuration,SpringBoot社区推荐使用基于JavaConfig的配置形式,所以,这里的启动类标注了@Configuration之后,本身其实也是一个IoC容器的配置类。
- 表现层形式
基于XML配置的的方式是这样:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
default-lazy-init="true"
>
<!-- bean定义 -->
</beans>
2
3
4
5
6
7
8
而基于JavaConfig的配置方式是这样:
@Configuration
public class MockConfiguration{
// bean定义
}
2
3
4
任何一个标注了@Configuration的Java类定义都是一个JavaConfig配置类
- 注册bean定义层面 基于XML的配置形式是这样:
<bean id="mockService" class="..MockServiceImpl">
...
</bean>
2
3
而基于JavaConfig的配置形式是这样的:
@Configuration
public class MockConfiguration{
@Bean
public MockService mockService() {
return new MockServiceImpl();
}
}
2
3
4
5
6
7
任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IOC容器,方法名将默认成该bean定义的id。
- 表达依赖注入关系层面
为了表达bean与bean之间的依赖关系,在XML形式中一般是这样:
<bean id="mockService" class="..MockServiceImpl">
<propery name="dependencyService" ref="dependencyService" />
</bean>
<bean id="dependencyService" class="DependencyServiceImpl"></bean>
2
3
4
而基于JavaConfig的配置形式是这样的:
@Configuration
public class MockConfiguration{
@Bean
public MockService mockService() {
return new MockServiceImpl(dependencyService());
}
@Bean
public DependencyService dependencyService() {
return new DependencyServiceImpl();
}
}
2
3
4
5
6
7
8
9
10
11
如果一个bean的定义依赖其他bean,则直接调用JavaConfig类中依赖bean的创建方法就可以了。
# @CompontentScan
@ComponentScan这个注解在Spring中很重要,他对应XML配置中的元素,@ComponentScan的功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository)或者bean定义,最终将这些bean定义加载到IoC容器中。 我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描
注:所以SpringBoot的启动类最好还是放在root package下,因为默认不指定basePackages。
# @EnableAutoConfiguration
个人感觉@EnableAutoConfiguration这个注解最为重要,所以放在最后来解释,大家是否还记得Spring框架提供的各种名字为@Enable开头的Annotation定义,比如@EnableScheduling,@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和做事方式其实一脉相承,简单概括,借助@Import的支持,收集和注册特定场景相关的bean定义。