01|项目示例
基于Spring boot构建一个简单的web项目
1、引入依赖 ```java <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0 white.colde spring-boot-study 0.0.1-SNAPSHOT spring-boot-study <java.version>11</java.version>
org.springframework.boot spring-boot-starter-parent 2.4.1 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-maven-plugin
- 2、创建测试接口
```java
@RestController
public class TestController {
@GetMapping
public String index(){
return "hello spring boot";
}
}
3、创建启动类 ```java @SpringBootApplication public class SpringBootStudyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootStudyApplication.class, args);
}
}
<a name="YXNcO"></a>
## 02|IoC容器源码解析
<a name="2F6J4"></a>
### 2.1|核心类
<a name="xA2H7"></a>
#### 1、SpringApplication
SpringBoot应用入口类,核心方法如下:
```java
public class SpringApplication{
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
// 创建应用上下文,会依据当前运行环境创建不同的应用上下文对象
// 由于这里为web环境,即此处创建的是AnnotationConfigServletWebServerApplicationContext对象
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 开始容器初始化,解析装载bean到容器当中
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
}
SpringApplication主要做以下几个工作:
- 执行容器初始化前的一些准备工作,如运行环境推断、解析根配置类信息等
- 创建应用上下文
-
2、AnnotationConfigServletWebServerApplicationContext
SpringBoot web环境下默认创建的上下文对象,其类图如下:
在SpringApplication创建了AnnotationConfigServletWebServerApplicationContext类的对象,并调用了其refresh方法,而refresh方法的具体实现是在其父类AbstractApplicationContext中。3、AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// 获取实际BeanFactory,默认实现是ConfigurableListableBeanFactory
// 该对象是在GenericApplicationContext的构造方法中初始化创建
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
// 提供了一个钩子方法供子类可以在BeanFactory准备工作完成后进行相应的逻辑处理调用
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
initMessageSource();
// 初始化事件派发器
initApplicationEventMulticaster();
// ⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
onRefresh();
// 注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean
registerListeners();
// 初始化所有剩下的非懒加载的单例Bean
finishBeanFactoryInitialization(beanFactory);
// 完成容器的初始化,发布事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
}
4、DefaultListableBeanFactory
GenericApplicationContext构造方法中创建了一个DefaultListableBeanFactory类的实例,DefaultListableBeanFactory是Spring注册和加载Bean的默认实现类,ApplicationContext有关操作皆委托由DefaultListableBeanFactory进行实现,其类图如下:
AliasRegistry:定义对alias的简单增删改等操作
- SimpleAliasRegistry:主要使用map作为alias的缓存,并对接口AliasRegistry进行实现
- SingletonBeanRegistry:定义对单例Bean的注册及获取
- BeanFactory:定义了获取Bean及Bean的各种属性
- HierarchicalBeanFactory:包含层次结构的BeanFactory,在BeanFactory的基础上增加了对parentFactory的支持
- BeanDefinitionRegistry:定义对BeanDefinition的各种增删改操作
- FactoryBeanRegistrySupport:在DefaultSingletonBeanRegistry基础上增加了对FactoryBean的特殊处理功能
- ConfigurableBeanFactory:提供配置Factory的各种方法
- ListableBeanFactory:根据各种条件获取Bean的配置清单
- AbstractBeanFactory:综合FactoryBeanRegistrySupport和ConfigurationBeanFactory的功能
- AutowireCapableBeanFactory:提供创建Bean、自动注入、初始化
- AbstractAutowireCapableBeanFactory:综合AbstractBeanFactory并对AutowireCapableBeanFactory进行实现
- ConfigurableListableBeanFactory:BeanFactory配置清单,指定忽略类型及接口等
- DefaultListableBeanFactory:综合上面的所有功能,本身提供对Bean注册后的一些处理功能