方法一:
this.prepareRefresh();
该方法主要作用:
1、设置容器的状态
2、初始化属性设置(应用监听器)
3、检查必备属性是否存在
方法二:
this.obtainFreshBeanFactory();
该方法主要作用:配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中
1、设置beanFactory序列化id
2、获取beanFactory
方法三:
this.prepareBeanFactory(beanFactory);
作用:主要是对beanFactory做一些类加载器的配置和需要忽略的依赖
1、设置beanFactory一些属性
2、添加后置处理器
3、设置忽略的自动装配接口
4、注册一些组件
方法四:
this.postProcessBeanFactory(beanFactory);
提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
作用:注册web请求相关的处理器(一般情况下,启动是为空的)
1、子类重写以在BeanFactory完成创建后做进一步设置
方法五:
this.invokeBeanFactoryPostProcessors(beanFactory);
作用:
1、调用BeanDefinitionRegistryPostProcessor实现向容器内添加bean的定义
2、用BeanFactoryPostProcessor实现向容器内Bean的定义的添加属性
方法六:
this.registerBeanPostProcessors(beanFactory);
作用:
1、找到BeanPostProcessor的实现
2、排序后注册到容器内
方法七:
this.initMessageSource();
作用:
1、初始化国际化相关属性
方法八:
this.initApplicationEventMulticaster();
作用:
1、初始化事件广播器
方法九:
this.onRefresh();
作用:该方法是一个空实现,是留给子类实现的。
1、主要内容是创建web容器
方法十:
this.registerListeners();
作用:
1、添加容器内事件监听器至事件广播器中
2、派发早期事件
方法十一:
this.finishBeanFactoryInitialization(beanFactory);
作用:
1、初始化所有剩下的单例bean
方法十二:
this.finishRefresh();
作用:
1、清空缓存
2、初始化生命周期处理器
3、调用化生命周期处理器onRfresh方法
4、发布ContextRefreshedEvent事件
5、JXM相关处理
方法十三:
this.resetCommonCaches();
作用:清除缓存
将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。
IoC 解决了什么问题:降低对象之间的耦合度;资源变的容易管理;比如你用 Spring 容器提供的话很容易就可以实现一个单例。
业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
AOP 解决了什么问题:在不改变原有业务逻辑的情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。
使用:@Aspect+@Component+@Pointcut(“@annotation(com.mxw.common.annotation.AccountInfo)”)+@Around(value = “pointcut()”)
@Component 注解作用于类,而@Bean注解作用于方法。
@Component:类路径扫描来自动侦测以及自动装配到 Spring 容器中;@Bean 注解通常是我们在标有该注解的方法中定义产生这个 bean。@Bean告诉了 Spring 这是某个类的实例,当我需要用它的时候还给我。
@Bean 注解比 @Component 注解的自定义性更强.当我们引用第三方库中的类需要装配到 Spring容器时,则只能通过 @Bean来实现
结论:@Bean注解的方法返回的实例已经注入到SpringIOC容器中,但是每次调用@Bean注解的方法时,都会创建新的对象实例bean返回,并不会从IOC容器中获取。
因此,要实现在@Bean注解方法时,要求从IOC容器中返回实例bean而不是每次都新创建一个对象,则@Bean要@Configuration配合使用
将一个类声明为 bean 的注解有哪些? @Component @Repository @Service @Controller
1.容器找到配置文件中 Spring Bean 的定义
2.容器利用 Java 反射 API 创建一个 Bean 的实例。
3.利用 set()方法设置一些属性值
4.如果 Bean 实现了 xxxAware 接口,调用 setxx()方法,设置对应的值。(BeanNameAware,BeanClassLoaderAware,BeanFactoryAware)。
5.如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行前置处理方法
6.自定义init-method
7.如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行后置处理方法
8.当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
Spring使用工厂模式可以通过 BeanFactory 或 ApplicationContext 创建 bean 对象
BeanFactory :延迟注入(使用到某个 bean 的时候才会注入),相比于ApplicationContext 来说会占用更少的内存,程序启动速度更快。
ApplicationContext :容器启动的时候,不管你用没用到,一次性创建所有 bean 。
BeanFactory 仅提供了最基本的依赖注入支持, ApplicationContext 扩展了 BeanFactory ,除了有BeanFactory的功能还有额外更多功能,所以一般开发人员使用 ApplicationContext会更多。
ClassPathXmlApplication:把上下文文件当成类路径资源。
FileSystemXmlApplication:从文件系统中的 XML 文件载入上下文定义信息。
XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义信息
MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。
1.客户端(浏览器)发送请求,直接请求到 DispatcherServlet、
2.DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。
3.由 HandlerAdapter 适配器处理。
4.HandlerAdapter 会根据Handler来调用真正的处理器开处理请求,并处理相应的业务逻辑.
5.处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。
6.ViewResolver 接收逻辑 View 查找实际的 View。
7.DispaterServlet把返回的Model传给View(视图渲染)。
8.把View返回给请求者(浏览器)
工厂设计模式 : Spring 使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象
代理设计模式 : Spring AOP 功能的实现。
单例设计模式 : Spring 中的 Bean 默认都是单例的
模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用
适配器模式 : Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller
声明式事务 : 在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)
PlatformTransactionManager:(平台)事务管理器,Spring 事务策略的核心。
TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。
TransactionStatus: 事务运行状态。
PlatformTransactionManager 接口可以被看作是事务上层的管理者,而 TransactionDefinition 和 TransactionStatus 这两个接口可以看作是事务的描述
PlatformTransactionManager接口中定义了三个方法:获得事务;提交事务,回滚事务
事务属性包含了 5 个方面:
隔离级别,
传播行为,
回滚规则(规则定义了哪些异常会导致事务回滚而哪些不会),
是否只读(只读事务不涉及数据的修改,数据库会提供一些优化手段,适合用在有多条数据库查询操作的方法中),
事务超时(指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务)
只读事务:
如果你一次执行单条查询语句,则没有必要启用事务支持,数据库默认支持 SQL 执行期间的读一致性;
如果你一次执行多条查询语句,例如统计查询,报表查询,在这种场景下,多条查询 SQL 必须保证整体的读一致性,否则,在前条 SQL 查询之后,后条 SQL 查询之前,数据被其他用户改变,则该次整体的统计查询将会出现读数据不一致的状态,此时,应该启用事务支持
事务传播行为是为了解决业务层方法之间互相调用的事务问题。
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。
TransactionDefinition.PROPAGATION_REQUIRED(默认):如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
ISOLATION_READ_UNCOMMITTED:可能会导致脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED :可以阻止脏读
ISOLATION_REPEATABLE_READ :可以阻止脏读和不可重复读
ISOLATION_SERIALIZABLE:都防止
@Transactional 的作用范围
方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。
类 :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。
接口 :不推荐在接口上使用。
@Transactional 的工作机制是基于 AOP 实现的,AOP 又是使用动态代理实现的。如果目标对象实现了接口,默认情况下会采用 JDK 的动态代理,如果目标对象没有实现了接口,会使用 CGLIB 动态代理。
若同一类中的其他没有 @Transactional 注解的方法内部调用有 @Transactional 注解的方法,有@Transactional 注解的方法的事务会失效。这是由Spring AOP代理的原因造成的,因为只有当 @Transactional 注解的方法在类以外被调用的时候,Spring 事务管理才生效。解决办法就是避免同一类中自调用或者使用 AspectJ 取代 Spring AOP 代理。
@Transactional 注解只有作用到 public 方法上事务才生效,不推荐在接口上使用;
避免同一个类中调用 @Transactional 注解的方法,这样会导致事务失效;
正确的设置 @Transactional 的 rollbackFor 和 propagation 属性,否则事务可能会回滚失败;
被 @Transactional 注解的方法所在的类必须被 Spring 管理,否则不生效;
底层使用的数据库必须支持事务机制,否则不生效
@SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。
@EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
@ComponentScan: 扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。
@Configuration:允许在 Spring 上下文中注册额外的 bean 或导入其他配置类
@Scope
singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
prototype : 每次请求都会创建一个新的 bean 实例。
request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
session : 每一个 HTTP Session 会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
@RequestBody
读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。
通过@Component+@ConfigurationProperties读取配置信息并与 bean 绑定。
javax.validation.constraints
@Valid RequestBody
@NotEmpty 被注释的字符串的不能为 null 也不能为空
@NotBlank 被注释的字符串非 null,并且必须包含一个非空白字符
@Validated+@Valid+@验证 验证请求参数(Path Variables 和 Request Parameters)
全局处理 Controller 层异常
@RestControllerAdvice :注解定义全局异常处理类
@ExceptionHandler :注解声明异常处理方法
json 数据处理
@JsonIgnoreProperties 作用在类上用于过滤掉特定字段不返回或者不解析。
@JsonIgnore一般用于类的属性上,作用和上面的@JsonIgnoreProperties 一样
@JsonFormat一般用来格式化 json 数据。
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern=“yyyy-MM-dd’T’HH:mm:ss.SSS’Z’”, timezone=“GMT”)
扁平化;@JsonUnwrapped
直接引入一个 starter,通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能。
@EnableAutoConfiguration:实现自动装配的核心注解
自动装配核心功能的实现实际是通过 AutoConfigurationImportSelector类。
selectImports方法:用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IoC 容器中
getAutoConfigurationEntry:判断自动装配开关是否打开;
用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName。
获取需要自动装配的所有配置类,读取META-INF/spring.factories
过程:
Spring Boot 通过@EnableAutoConfiguration开启自动装配,通过 SpringFactoriesLoader 最终加载META-INF/spring.factories中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional按需加载的配置类,想要其生效必须引入spring-boot-starter-xxx包实现起步依赖
第一步,创建threadpool-spring-boot-starter工程
第二步,引入 Spring Boot 相关依赖
第三步,创建ThreadPoolAutoConfiguration
第四步,在threadpool-spring-boot-starter工程的 resources 包下创建META-INF/spring.factories文件
最后新建工程引入threadpool-spring-boot-starter
定义一个事件: 实现一个继承自 ApplicationEvent,并且写相应的构造函数;
定义一个事件监听者:实现 ApplicationListener 接口,重写 onApplicationEvent() 方法;
使用事件发布者发布消息: 可以通过 ApplicationEventPublisher 的 publishEvent() 方法发布消息