1.Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化
2.Bean实例化后对将Bean的引入和值注入到Bean的属性中
3.如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法
4.如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
5.如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
6.如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。
7.如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
8.如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。
9.此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。
10.如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
(1)客户端发起HTTP请求:客户端将请求提交到DispatcherServlet。
(2)寻找处理器:由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理该请求的Controller。
(3)调用处理器:DispatcherServlet将请求提交到Controller。
(4)调用业务处理逻辑并返回结果:Controller调用业务处理逻辑后,返回ModelAndView。
(5)处理视图映射并返回模型:DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图。
(6)HTTP响应:视图负责将结果在客户端浏览器上渲染和展示。
// 访问模型层得到数据
User user = userService.getUser(id);
// 模型和视图
ModelAndView mv = new ModelAndView();
// 定义模型视图
mv.setViewName("user/details");
// 加入数据模型
mv.addObject("user", user);
// 返回模型和视图
return mv;
Spring Boot的启动流程
(1)项目启动时,调用入口类MySpringBootApplication的main方法。
(2)入口类MySpringBootApplication的main方法会调用SpringApplication的静态方法run。
(3)在run方法中首先创建一个SpringApplication对象实例,然后调用SpringApplication对象实例的run方法。
(4)查询和加载所有的SpringApplicationListener监听器。
(5)SpringApplicationListener监听器调用其starting方法,Spring Boot通知这些SpringApplicationListener监听器,我马上要开始执行了。
(6)创建和准备Spring Boot应用将要使用的Environment环境,包括配置要使用的PropertySource以及Profile。
(7)创建和初始化应用上下文ApplicationContext。这一步只是备工作,并未开始正式创建。
(8)这一步是最重要的,Spring Boot会通过@EnableAutoConfiguration获取所有配置以及其他形式的IoC容器配置加载到已经准备完毕的ApplicationContext。
(9)主要是调用ApplicationContextInitializer类的initialize方法对应用上下文进行设置和处理。
(10)调用ApplicationContext上下文的refresh方法,使Ioc容器达到可用状态。
(11)查找当前ApplicationContext上下文是否注册有ApplicationRunner与CommandLineRunner,如果有,循环遍历执行ApplicationRunner和CommandLineRunner的run方法。
(12)执行SpringApplicationListener的finished方法,Spring Boot应用启动完毕。(一步一步学Spring Boot:微服务项目实战(第2版))
(1)使用 @Configuration与@Bean注解。
(2)使用@Controller、@Service、@Repository、@Component注解标注该类,然后启用@ComponentScan自动扫描。
(3)使用@Import方法。
Spring Boot中采取第3种方法,@EnableAutoConfiguration注解中使用@Import({AutoConfigurationImportSelector.class})注解
在Spring中,数据库事务是通过AOP技术来提供服务的。在JDBC中存在着大量的try…catch…finally…语句,也同时存在着大量的冗余代码,如那些打开和关闭数据库连接的代码以及事务回滚的代码。使用Spring AOP后,Spring将它们擦除了,你将看到更为干净的代码,没有那些try…catch…finally…语句,也没有大量的冗余代码。不过,在讨论那些高级话题之前,我们需要先从简单的知识入手,并且讲述关于数据库隔离级别的内容,否则有些读者会很难理解后面的内容(深入浅出Spring Boot 2.x(异步图书))
在Spring数据库事务中可以使用编程式事务,也可以使用声明式事务。大部分的情况下,会使用声明式事务。编程式事务这种比较底层的方式已经基本被淘汰了,Spring Boot也不推荐我们使用,因此这里不再讨论编程式事务。(深入浅出Spring Boot 2.x(异步图书))
对于事务,需要通过标注告诉Spring在什么地方启用数据库事务功能。对于声明式事务,是使用@Transactional进行标注的。这个注解可以标注在类或者方法上,当它标注在类上时,代表这个类所有公共(public)非静态的方法都将启用事务功能。在@Transactional中,还允许配置许多的属性,如事务的隔离级别和传播行为,这是本章的核心内容;又如异常类型,从而确定方法发生什么异常下回滚事务或者发生什么异常下不回滚事务等。这些配置内容,是在Spring IoC容器在加载时就会将这些配置信息解析出来,然后把这些信息存到事务定义器(TransactionDefinition接口的实现类)里,并且记录哪些类或者方法需要启动事务功能,采取什么策略去执行事务。这个过程中,我们所需要做的只是给需要事务的类或者方法标注@Transactional和配置其属性而已,并不是(深入浅出Spring Boot 2.x(异步图书))
public @interface Transactional {
// 通过bean name 指定事务管理器
@AliasFor("transactionManager")
String value() default "";
// 同value属性
@AliasFor("value")
String transactionManager() default "";
// 指定传播行为
Propagation propagation() default Propagation.REQUIRED;
// 指定隔离级别
Isolation isolation() default Isolation.DEFAULT;
// 指定超时时间(单位秒)
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
// 是否只读事务
boolean readOnly() default false;
// 方法在发生指定异常时回滚,默认是所有异常都回滚
Class extends Throwable>[] rollbackFor() default {};
// 方法在发生指定异常名称时回滚,默认是所有异常都回滚
String[] rollbackForClassName() default {};
// 方法在发生指定异常时不回滚,默认是所有异常都回滚
Class extends Throwable>[] noRollbackFor() default {};
package org.springframework.transaction.annotation;
/**** imports ****/
public enum Propagation {
/**
* 需要事务,它是默认传播行为,如果当前存在事务,就沿用当前事务,
* 否则新建一个事务运行子方法
*/
REQUIRED(TransactionDefinition.PROPAGATION_REQUIRED),
/**
* 支持事务,如果当前存在事务,就沿用当前事务,
* 如果不存在,则继续采用无事务的方式运行子方法
*/
SUPPORTS(TransactionDefinition.PROPAGATION_SUPPORTS),
/**
* 必须使用事务,如果当前没有事务,则会抛出异常,
* 如果存在当前事务,就沿用当前事务
*/
MANDATORY(TransactionDefinition.PROPAGATION_MANDATORY),
/**
* 无论当前事务是否存在,都会创建新事务运行方法,
* 这样新事务就可以拥有新的锁和隔离级别等特性,与当前事务相互独立
*/
REQUIRES_NEW(TransactionDefinition.PROPAGATION_REQUIRES_NEW),
/**
* 不支持事务,当前存在事务时,将挂起事务,运行方法
*/
NOT_SUPPORTED(TransactionDefinition.PROPAGATION_NOT_SUPPORTED),
/**
* 不支持事务,如果当前方法存在事务,则抛出异常,否则继续使用无事务机制运行
*/
NEVER(TransactionDefinition.PROPAGATION_NEVER),
/**
* 在当前方法调用子方法时,如果子方法发生异常,
* 只回滚子方法执行过的SQL,而不回滚当前方法的事务
*/
NESTED(TransactionDefinition.PROPAGATION_NESTED);
private final int value;
Propagation(int value) { this.value = value; }
public int value() { return this.value; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)