MyBatis
MyBatis 执行流程
- SqlSessionFactory获取SqlSession
- TransactionFactory新建Transaction
- 根据Transaction和ExecutorType(Simple,Reuse,Batch)通过Configuration获取Executor(中间InteceptorChain适配插件)
- 参数Configuration,Executor和Autocommit创建DefaultSqlSession
- Select(statement,param,RowBounds,ResultHandler)
- 根据statement获取MapperStatement
- 根据不同的Executor(BaseExecutor,CacheExecutor)调用query()
- MapperStatement根据param获取BoundSql(封装参数和sql)
- 创建CacheKey
- 从一级缓存中获取(BaseExecutor)
- 如果一级缓存中获取不到,则创建StatementHandler(中间InteceptorChain适配插件)
- 对Statement进行预处理(设置超时,参数等)
- Statement执行sql
- ResultSetHandler对结果进行封装
MyBatis为什么@Autowired即可注入实现类
- MapperScannerConfigurer实现 BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
- Spring默认注入MapperFactoryBean 代码(definition.setBeanClass(this.mapperFactoryBean.getClass()))
- MapperFactoryByean.getObject()
- getSqlSession().getMapper(this.mapperInterface);
- DefaultSession.getMapper()
- 通过Configuration获取Mapper(Class, DefaultSession)
- 通过Configuration的MapperRegistry.getMapper(Class, DefaultSession()
- 通过Configuration的MapperRegistry.getMapper(Class, DefaultSession)
- 根据Class获取MapperProxyFactory
- MapperProxyFactory.newInstance()
- 根据SqlSesison,MapperInterface创建MapperProxy
- Proxy.newProxyInstance()
Spring
启动流程
- prepareRefresh() - 准备此上下文以进行刷新,设置其启动日期和活动标志以及执行属性源的任何初始化。
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory() - 告诉子类刷新内部bean工厂。
- 如果存在beanFactory则销毁。
- 创建beanFastory(DefaultListableBeanFactory),并且装在配置文件
- prepareBeanFactory(beanFactory) - 准备bean工厂以在此上下文中使用(预处理 例:设置类加载器,设置忽略等)。
- postProcessBeanFactory(beanFactory) - 允许在上下文子类中对bean工厂进行后处理。(例如Mybatis的Confituration通过实现该方法,自定义实现注入MapperFactoryBean,后续获取Mapper实现类在通过MapperFactoryBean来获取)
- invokeBeanFactoryPostProcessors(beanFactory) - 在上下文中调用注册为beanFactory的后置处理器。
- 获取实现PriorityOrdered的BeanDefinitionRegistryPostProcessor,排序并调用
- 获取实现Ordered的BeanDefinitionRegistryPostProcessor,排序并调用
- 调用其他的BeanDefinitionRegistryPostProcessor
- registerBeanPostProcessors(beanFactory) - 注册拦截bean创建的bean处理器。
- 获取实现PriorityOrdered的BeanPostProcessors,排序并调用
- 获取实现Ordered的BeanPostProcessors,排序并调用
- 调用其他的BeanPostProcessors
- initMessageSource() - 初始化国际化相关
- initApplicationEventMulticaster() - 初始化事件广播器(观察者模式)
- onRefresh() - 在特定的上下文子类中初始化其他特殊bean(空实现,有需要子类来实现)。(模板方法模式,此方法又称钩子方法)
- registerListeners() - 注册监听器(在事件广播器中注册)
- finishBeanFactoryInitialization(beanFactory) - 完成工厂初始化(实例化所有剩余的[非延迟初始化]单例 注:默认都为懒加载)。
- finishRefresh() - 完成容器初始化(发布上下文刷新事件)
循环依赖解决
入口: AbstractBeanFactory#doGetBean
Spring 注入对象分为三个步骤
- createBeanInstance: 实例化(构造器)
- populateBean: 填充属性(设置字段)
- initializeBean: init 方法
Sring 解决循环依赖依靠三级缓存
/** * Cache of singleton objects: bean name –> bean instance * 完成初始化的单例对象的cache (一级缓存) */ private final Map singletonObjects = new ConcurrentHashMap(256); /** * Cache of early singleton objects: bean name –> bean instance * 完成实例化但是尚未初始化的,提前暴光的单例对象的Cache (二级缓存) */ private final Map earlySingletonObjects = new HashMap(16); /** * Cache of singleton factories: bean name –> ObjectFactory * 进入实例化阶段的单例对象工厂的cache (三级缓存) */ private final Map> singletonFactories = new HashMap>(16);
- 调用父类 DefaultSingletonBeanRegistry#getSingleton(String beanName, boolean allowEarlyReference)
- 如果一级缓存中有, 则说明已经初始化, 直接使用
- 如果一级缓存中没有, 但是正在创建.
- 如果二级缓存中没有, 则手动创建并且将对象放入二级缓存, 并将三级缓存中的实例对象清除
- 如果二级缓存有, 则使用
- 如果没有, 则返回 null
- 如果没有获取到对象, 则说明需要实例化该对象 DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)
- 第一步, 预先将该对象名称放入singletonsCurrentlyInCreation, 表示正在创建
- 实例化该对象
- 设置该对象属性
- 执行 init
- 放入一级缓存并从二级缓存中清除
Feign
- 自动配置入口: FeignClientsRegistrar#registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry)
- 注入 feign 类: FeignClientsRegistrar#registerFeignClient
private void registerFeignClient(BeanDefinitionRegistry registry,
AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
String className = annotationMetadata.getClassName();
BeanDefinitionBuilder definition = BeanDefinitionBuilder
.genericBeanDefinition(FeignClientFactoryBean.class);
validate(attributes);
definition.addPropertyValue("url", getUrl(attributes));
definition.addPropertyValue("path", getPath(attributes));
String name = getName(attributes);
definition.addPropertyValue("name", name);
definition.addPropertyValue("type", className);
definition.addPropertyValue("decode404", attributes.get("decode404"));
definition.addPropertyValue("fallback", attributes.get("fallback"));
definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
...
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
}
- 自动配置类: FeignAutoConfiguration (默认使用 URLConnection, 可选择 ApacheHttpClient 还是 OkHttpClient )
- FactoryBean.getObject() -> FeignClientFactoryBean.getObject()
- 设置属性: FeignClientFactoryBean#feign()
- Encoder
- Dncoder
- Contact (SpringMvcContract 通过继承BaseContract, 默认注册AnnotatedParameterProcessor的子类来实现支持 Spring 注解. 即RequestHeader, RequestParam, PathVariable等注解)
- 拼接 URL, 负载均衡
- feign.Feign.Builder#target(feign.Target)
- build(): 设置客户端, 重试, 拦截器, encoder, decoder
- instance(): 构造动态代理 (SynchronousMethodHandler)
- 动态代理执行: SynchronousMethodHandler#invoke
- 根据 metadata 创建RequestTemplate(设置urlIndex, bodyIndex, headerMapIndex, queryMapIndex等)
- 解析 encode(ReflectiveFeign.BuildTemplateByResolvingArgs#resolve)
- 使用原型模式克隆 Retryer
- 执行和解析: SynchronousMethodHandler#executeAndDecode
- 执行拦截器: feign.SynchronousMethodHandler#targetRequest
- 执行请求: client.execute(request, options)
- 根据不同的状态码解析结果
- 如果需要重试则重试, 返回结果
线程池
原理
-
判断是否超过核心线程if (workerCountOf(c) < corePoolSize)
1.1 没有超过则新建线程addWorker(command, true)
1.2 如果超过则执行第二步
-
尝试往工作队列里放入if (isRunning(c) && workQueue.offer(command))
1.1 放入成功则退出
1.2 放入失败则执行第三步
-
新建线程(但是小于最大线程)