区别spring springboot springMVC
spring是ioc容器,管理bean ioc aop 不同类不同方法共同处理抽象成切面 自动注入
mvc对web框架的解决方案,前端控制器 接收请求 路由策略 适配到handle 视图解析器
boot是快速开发工具包,约定大于配置,一系列解决方案 开箱即用
注解boot
springBootApplication:表示工程 springBootConfiguration,enableAutoConfiguration(导入selector加载classPath下SpringFactories自动配置类) componentScan扫描路径
bean:定义bean
controller service responseBody autowired
启动tomcat
创建容器,conditionalOnClass是否依赖tomcat,存在则生成启动tomcat的bean,容器创建完之后 获取启动tomcat的bean 创建tomcat 绑定端口 启动tomcat
applicationContext 和 beanFactory
b生成/维护bean;延迟加载实例化bean
a继承了beanFactory,还继承environmentCapable/messageSource/applicationEventPubliser接口获取系统变量 国际化 事件发布等功能
统一资源文件访问方式,提供在监听器中注册bean的事件,加载多个配置文件
载入多个上下文,每个专注于特定的层次
容器启动一次性创建所有的bean,占用内存空间,可以声明的方式被创建
start
轻量级开源的j2ee框架,容器框架 装javabean aop ioc
定义一个starter的jar包,写一个configuration配置类,将bean定义其中,在starter包的meta-inf/spring.factories中写入配置类,springboot会按约定加载该配置类
ioc:重中之重
配置文件配置包扫描路径 获取class文件 反射确定需要ioc管理的类 对需要注入的类依赖注入
定义一些注解,控制层 业务层 数据持久层 依赖注入注解 获取配置文件
获取指定路径下的文件信息及文件夹信息,class文件添加到set集合
遍历集合 获取指定注解的类 交给ioc,安全的map存储对象
遍历ioc容器 获取类实例 判断是否依赖其他类实例 递归注入
ioc容器实际map,存各种对象,反射创建对象放入map中
代码需要用到里面的对象,通过类型/🆔(对象名)注入;没有对象伤不起
控制反转:需要对象时IOC主动创建/使用 对象
依赖注入:IOC容器运行期间 ,动态将某种依赖关系注入到对象中
加载
spring框框干活,一干一个不吱声
ioc容器:读取配置信息 实例化 管理对象
bean定义:描述 配置要管理的对象,对象类名 属性 依赖关系
bean工厂:实例化 配置管理对象,读取bean定义 据定义创建 初始化bean对象 放入ioc容器
生命周期:尊重生命 热爱生活
上图 虽然一张图胜过千言万语 但是我画的也不是图 死板的流程图罢了
初始化细化一下:
initializingBean 检查对象实现了这个接口 执行afterPropertiesSet方法 定制初始化逻辑
init-method:配置类这个属性,调用配置方法 执行初始化立即 @postConstruct
启动流程
作用域
单例singleton:每个容器一个bean实例,beanFactory维护
prototype原型:每次请求都注入新的实例
request:http请求创建一个单例对象
session:每个session中有个bean实例
application:servletContext生命周期中复用单例对象
websocket:定义在websocket生命周期的
global全局
配置文件加载顺序
越后优先级越低:会被覆盖
命令行参数 java系统属性 操作系统环境变量 外部properties/yml文件
内部properties/yml配置文件 @propertySource
自动配置
import + configuration + spring spi
自动配置类由各starter提供,使用@configuration+bean定义配置类,当道meta-inf/spring.factories下,spi扫描配置类
设计模式:低耦合两个字yyds
工厂beanFactory(传入的标识获取bean对象)/factoryBean(实现该接口,getObjects)
适配器advisorAdapter/handlerAdater
访问者propertyAccessor
装饰器beanWrapper
代理aop
观察者事件监听
策略instantiationStrategy
模板jdbcTemplate
委派beanDefinitionParseDefenate
责任链beanPostProcessor
aop:这块嘎嘎🦆厉害
CGLIB通过创建目标类的子类来代理原始对象,并在子类中添加增强处理
代理类class文件加载 修改字节码生成子类
jdk基于接口 proxy类 被代理对象注入到中间对象
中间对象实现invocationHandler接口(拦截器 反射 代理接口匿名类)
newProxyInstance利用中间对象来生产代理对象
事务:
数据库事务和aop机制
@Transactional注解bean创建代理对象作为bean
调用代理对象方法先判断方法上是否加了Transactional注解
如果咱就说如果加了 利用事务管理器 创建数据库连接 autocommit=false
spring事务传播机制是spring自己实现的,基于数据库连接做的
一个数据库连接一个事务,这句话挺重要的!新开一个事务 先建连接再执行sql
事务创建/提交/回滚通过transactionInterceptor切面完成,据事务管理器和属性自动管理
platformTransactionManager实现
dataSourceTransactionManager:jdbc和mybatis的
jtaTransctionManager:分布式事务 xa接口 多资源事务管理
spring事务核心 transactionDefinition定义属性(隔离级别/传播行为/超时/只读)和transactionStatus(是否新事物/是否标记为回滚)
半事务 MQ
TCC :try-confirm-cancel
万字长文漫谈分布式事务实现原理 - 知乎
失效
私有方法 / 未被spring管理 /方法用final修饰/方法内部调用/未开启事务
传播属性
propagation_required 当前则没有新建,有则加入,默认
propagationrequiresnew 当前存在挂起 新建事务(和挂起的无关) 内抛异常外层捕获可不处理
propagation_supports支持当前事务,无事务 非事务方式执行
propagation_mandatory支持当前事务 没有抛异常
propagationnotsupported以非事务方式操作 当前存在则挂起
propagation_never非事务方式执行,存在事务抛异常
propagation_nested活动事务存在 运行一个嵌套事务中,无required执行使用单独事务,使用独立事务,拥有多个回滚的保存点,内部事务的回滚不会对外部事务造成影响,只对datasourceTransactionManager事务管理器有效
【MySQL】事务原理_mysql事务原理-CSDN博客
循环依赖
三级缓存
lazy解决构造方法造成的循环依赖问题
一级缓存 初始化的单例对象 singletonObjects
二级earlySingletonObjects缓存保存new出来的不完整对象,当单例池中找不到依赖的属性时,先从二级缓存中获取不完整对象,完成对象创建,后续依赖注入中 单例池中对象引用关系调整完成
三级缓存singletonFactories,引用对象配置了aop,单例池中最终会需要注入动态代理对象(对象初始化之后才开始),非原对象,保存所有对象的动态代理配置信息,发现有循环依赖时 获取代理对象 提前aop
后置处理器
beanFactory后置处理器BeanFactoryPostProcessor,spring启动先创建beanFactory实例 实例化所有bean后 依赖注入前,后置处理器加工beanFactory,spring扫描基于beanFactory实现
bean后置处理器BeanPostProcessor,先实例对象,bean后置处理器对该对象加工,依赖注入给autowired自动赋值,aop基于原实例对象进行动态代理,生成代理对象
springmvc组件
handler处理器:对应着controller层,@requestMapping标注的方法可看成handler
handlerMapping:initHandlerMappings(context)处理器映射器,据用户请求资源url查找handler
handlerAdapter:initHandlerAdapter(context)适配器,servlet处理方法的结构固定,request response为参数,调用灵活的handler来处理请求
handlerExceptionResolver:处理异常,据异常设置modelAndView,之后再交给render方法渲染
viewResolver:将视图名和local解析为view类型的视图,找到渲染用的模板和技术,具体渲染过程交给不同视图自己完成
requestToViewNameTranslator:有的handler处理完没有设置view也没有viewName,需要request中取viewName,只能有一个,request到viewName的转换规则都在一个translator里面
localeResolver:解析视图需要视图名和locale,视图名是处理器返回到,locale是localeResolver从request中解析出来的;表示一个区域 有了这个可以对不同区域用户显示不同结果集
themeResolver:解析主题,一个主题对应一个properties文件,存放着跟当前主题相关的资源,themeResolver themeSource theme,名称获取主题文件 主题获取资源
multipartResolver:上传请求,处理方法是将普通的request包装成initMultipartResolver
flashMapManager:管理flashMap redirect传递参数
SpringMVC原理与工作流程_springmvc原理及流程-CSDN博客
控制器单例:线程安全问题
scop非singleton,设计成无状态模式
mybatis与hibernate对比
h是orm框架
mybatis#{} ${}
#预编译处理,占位符,防sql注入,处理时 替换为? preparedStatement赋值
$字符串替换,拼接符,statement替换
插件运行原理
mybatis支持针对parameterHandler/resultSetHandler/StatementHandler/executor接口等插件
jdk动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能
invocationHandler方法的invoke方法
编写插件:实现mybatis的interceptor接口复写intercept方法,给插件编写注解
mybatis优缺点
基于sql语句编程,灵活 不会对程序现有设计造成影响,sql写在xml里,解除sql与程序代码的耦合,动态编写sql 可重用
减少代码量,各种数据库兼容,只要jdbc支持的库都可
映射标签,支持对象与数据库orm字段关系映射
sql编写工作量大,依赖数据库,不能随意更换数据库