赞
踩
springboot 启动类有两大核心: 一个是注解@SpringBootApplication,一个是main方法里面的SpringApplication.run。
1、通过main方法 启动springboot
2、首先进入SpringAplication类run方法
3、run方法新建SpringApplication对象
4、SpringApplication对象的run方法,首先创建并启动计时监控类
5、接着调用getRunListeners创建所有spring监听器
6、接着DefaultApplicationArguments初始化应用应用参数
7、接着prepareEnvironment根据运行监听器和参数准备spring环境
8、接着调用createApplicationContext方法创建应用上下文
9、通过prepareContext准备应用上下文
10、refreshContext方法刷新上下文(通过spring ioc模板方法初始化)
11、调用stop方法停止计时监控器类
12、调用started发布应用上下文 启动完成事件
13、callRunners方法执行所有runner运行器
14、调用running发布应用上下文就绪事件
15、最后返回应用上下文
- // run方法新建SpringApplication对象
- public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
- // SpringApplication对象的run方法
- return new SpringApplication(primarySources).run(args);
- }
-
-
- // SpringApplication对象的run方法
- public ConfigurableApplicationContext run(String... args) {
- StopWatch stopWatch = new StopWatch();
- // 首先创建并启动计时监控类
- stopWatch.start();
- ConfigurableApplicationContext context = null;
- Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
- configureHeadlessProperty();
- // 创建所有spring监听器
- SpringApplicationRunListeners listeners = getRunListeners(args);
- listeners.starting();
- try {
- // DefaultApplicationArguments初始化应用应用参数
- ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
- // prepareEnvironment根据运行监听器和参数准备spring环境
- ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
- configureIgnoreBeanInfo(environment);
- Banner printedBanner = printBanner(environment);
- // 调用createApplicationContext方法创建应用上下文
- context = createApplicationContext();
- exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
- new Class[] { ConfigurableApplicationContext.class }, context);
- // 通过prepareContext准备应用上下文
- prepareContext(context, environment, listeners, applicationArguments, printedBanner);
- // refreshContext方法刷新上下文(通过spring ioc模板方法初始化)
- refreshContext(context);
- afterRefresh(context, applicationArguments);
- // 调用stop方法停止计时监控器类
- stopWatch.stop();
- if (this.logStartupInfo) {
- new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
- }
- // 调用started发布应用上下文 启动完成事件
- listeners.started(context);
- // callRunners方法执行所有runner运行器
- callRunners(context, applicationArguments);
- }
- catch (Throwable ex) {
- handleRunFailure(context, ex, exceptionReporters, listeners);
- throw new IllegalStateException(ex);
- }
-
- try {
- // 调用running发布应用上下文就绪事件
- listeners.running(context);
- }
- catch (Throwable ex) {
- handleRunFailure(context, ex, exceptionReporters, null);
- throw new IllegalStateException(ex);
- }
- // 最后返回应用上下文
- return context;
- }
@SpringBootApplication包括三个注解和四个元注解:
元注解是指注解的注解,Java中有:
① @Retention: 定义注解的保留策略
② @Target:定义注解的作用目标
③ @Document:说明该注解将被包含在javadoc中
④ @Inherited:说明子类可以继承父类中的该注解
1、@EnableAutoConfiguration:SpringBoot根据应用所声明的依赖来对Spring框架进行自动配置。是借助@Import将所有符合自动配置条件的bean定义加载到IoC容器。
2、@SprinbootConfiguration:它是JavaConfig形式的Spring IOC容器的配置类。被标注的类类似于在spring的XML配置文件中(applicationContext.xml),装配所有bean事务,提供了一个spring的上下文环境。
3、@ComponentScan:组件扫描,可自动发现和装配Bean,@ComponentScan进行package进行扫描。
4、关于java元注解:
① @Retention: 定义注解的保留策略
② @Target:定义注解的作用目标
③ @Document:说明该注解将被包含在javadoc中
④ @Inherited:说明子类可以继承父类中的该注解
springboot执行流程UML图
1、springboot 开始启动(main方法)
2、new Springpplication()构造一个Spring应用
(1)、配置source
(2)、配置是否web环境
(3)、创建初始化构造器
(4)、创建应用监听器
(5)、配置主方法所在类
3、SpringApplication启动此应用
4、启动计时器和监听器(HeadLess模式配置)
(1)、启动监听模块
1)、启动
2)、监听
a、环境配置
b、应用上下文
3)、结束
(2)、启动环境模块
1)、创建配置环境
2)、加载属性文件资源
3)、配置监听
(3)、Beanner配置
(4)、启动应用程序上下文
1)、创建应用上下文
2)、基本属性配置
a、加载环境配置
b、资源加载器
c、配置监听
d、加载启动参数
3)、更新应用程序上下文
a、准备所需环境bean的工厂
b、通过工厂生产bean,通过stop停止计时器和监听器,SpringApplication启动结束
5、通过2.2和2.3获取的构造器监听器和4.4.3.a获取的工厂对象得到工厂集合
6、获取工厂类名和类加载器
7、通过类加载器获取spring.factories文件
8、获取工厂类的全路径
9、通过类路径反射获得工厂的class对象、构造方法。
10、生成工厂类实例返回
1)JDK代理使用的是反射机制实现AOP的动态代理;CGLIB代理使用字节码处理框架asm,对代理对象类的class文件加载进来,通过修改字节码生成子类。
2)JDK创建代理对象效率较高,执行效率较低;CGLIB创建效率较低,执行效率高。
3)JDK动态代理机制是委托机制,具体说动态实现接口类;CGLIB则使用的继承机制,具体说被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的。
4)JDK只能对实现接口的类生成代理;CGLIB是针对类实现代理,因为是继承机制,不能代理final修饰的类。
2、使用JDK还是CGLIB
1)如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。
2)如果目标对象实现了接口,可以强制使用CGLIB实现AOP。
3)如果目标对象没有实现了接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。