《JAVA核心知识》学习笔记(6. Spring 原理)-5

它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。可是 Spring
仍然能够和其余的框架无缝整合。
6.1.1. Spring 特色
6.1.1.1. 轻量级
6.1.1.2. 控制反转
6.1.1.3. 面向切面
6.1.1.4. 容器
6.1.1.5. 框架集合
 html

6.1.7. Spring IOC 原理
6.1.7.1. 概念
Spring 经过一个配置文件描述 Bean 及 Bean 之间的依赖关系,利用 Java 语言的反射功能实例化
Bean 并创建 Bean 之间的依赖关系。 Spring 的 IoC 容器在完成这些底层工做的基础上,还提供
了 Bean 实例缓存、生命周期管理、 Bean 实例代理、事件发布、资源装载等高级服务
 java

6.1.7.2. Spring 容器高层视图
Spring 启动时读取应用程序提供的 Bean 配置信息,并在 Spring 容器中生成一份相应的 Bean 配
置注册表,而后根据这张注册表实例化 Bean,装配好 Bean 之间的依赖关系,为上层应用提供准
备就绪的运行环境。 其中 Bean 缓存池为 HashMap 实现
 web

6.1.7.3. IOC 容器实现
BeanFactory-框架基础设施
BeanFactory 是 Spring 框架的基础设施,面向 Spring 自己; ApplicationContext 面向使用
Spring 框架的开发者,几乎全部的应用场合咱们都直接使用 ApplicationContext 而非底层
的 BeanFactory。
 spring

ApplicationContext 面向开发应用
ApplicationContext 由 BeanFactory 派 生 而 来 , 提 供 了 更 多 面 向 实 际 应 用 的 功 能 。
ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础
上,还经过多个其余的接口扩展了 BeanFactory 的功能sql

 

1.1..1.1.1 BeanDefinitionRegistry 注册表数据库

1. Spring 配置文件中每个节点元素在 Spring 容器里都经过一个 BeanDefinition 对象表示,
它描述了 Bean 的配置信息。而 BeanDefinitionRegistry 接口提供了向容器手工注册
BeanDefinition 对象的方法。
1.1..1.1.2 BeanFactory 顶层接口

 

2. 位于类结构树的顶端 ,它最主要的方法就是 getBean(String beanName),该方法从容器中
返回特定名称的 Bean, BeanFactory 的功能经过其余的接口获得不断扩展:
1.1..1.1.3 ListableBeanFactory

3. 该接口定义了访问容器中 Bean 基本信息的若干方法,如查看 Bean 的个数、获取某一类型
Bean 的配置名、查看容器中是否包括某一 Bean 等方法;
1.1..1.1.4 HierarchicalBeanFactory 父子级联编程

4. 父子级联 IoC 容器的接口,子容器能够经过接口方法访问父容器; 经过
HierarchicalBeanFactory 接口, Spring 的 IoC 容器能够创建父子层级关联的容器体系,子
容器能够访问父容器中的 Bean,但父容器不能访问子容器的 Bean。 Spring 使用父子容器实
现了不少功能,好比在 Spring MVC 中,展示层 Bean 位于一个子容器中,而业务层和持久
层的 Bean 位于父容器中。这样,展示层 Bean 就能够引用业务层和持久层的 Bean,而业务
层和持久层的 Bean 则看不到展示层的 Bean
1.1..1.1.5 ConfigurableBeanFactory
5. 是一个重要的接口,加强了 IoC 容器的可定制性,它定义了设置类装载器、属性编辑器、容
器初始化后置处理器等方法;
 后端

6. 定义了将容器中的 Bean 按某种规则(如按名字匹配、按类型匹配等)进行自动装配的方法;
1.1..1.1.7 SingletonBeanRegistry 运行期间注册单例 Bean

7. 定义了容许在运行期间向容器注册单实例 Bean 的方法;对于单实例( singleton)的 Bean
来讲, BeanFactory 会缓存 Bean 实例,因此第二次使用 getBean() 获取 Bean 时将直接从
IoC 容器的缓存中获取 Bean 实例。 Spring 在 DefaultSingletonBeanRegistry 类中提供了一
个用于缓存单实例 Bean 的缓存器,它是一个用 HashMap 实现的缓存器, 单实例的 Bean 以
beanName 为键保存在这个 HashMap 中。
1.1..1.1.8 依赖日志框框
8. 在初始化 BeanFactory 时,必须为其提供一种日志框架,好比使用 Log4J, 即在类路径下提
供 Log4J 配置文件,这样启动 Spring 容器才不会报错设计模式

 

ApplicationContext 面向开发应用
ApplicationContext 由 BeanFactory 派 生 而 来 , 提 供 了 更 多 面 向 实 际 应 用 的 功 能 。
ApplicationContext 继承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基础
上,还经过多个其余的接口扩展了 BeanFactory 的功能:api

 

1. ClassPathXmlApplicationContext:默认从类路径加载配置文件
2. FileSystemXmlApplicationContext:默认从文件系统中装载配置文件
3. ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器启动事
件、关闭事件等。
4. MessageSource:为应用提供 i18n 国际化消息访问的功能;
5. ResourcePatternResolver : 所 有 ApplicationContext 实现类都实现了相似于
PathMatchingResourcePatternResolver 的功能,能够经过带前缀的 Ant 风格的资源文
件路径装载 Spring 的配置文件。
6. LifeCycle:该接口是 Spring 2.0 加入的,该接口提供了 start()和 stop()两个方法,主要
用于控制异步处理过程。在具体使用时,该接口同时被 ApplicationContext 实现及具体
Bean 实现, ApplicationContext 会将 start/stop 的信息传递给容器中全部实现了该接
口的 Bean,以达到管理和控制 JMX、任务调度等目的。
7. ConfigurableApplicationContext 扩展于 ApplicationContext, 它新增长了两个主要
的方法: refresh()和 close(),让 ApplicationContext 具备启动、刷新和关闭应用上下
文的能力。在应用上下文关闭的状况下调用 refresh()便可启动应用上下文,在已经启动
的状态下,调用 refresh()则清除缓存并从新装载配置信息,而调用 close()则可关闭应用
上下文
 

WebApplication 体系架构
WebApplicationContext 是专门为 Web 应用准备的,它容许从相对于 Web 根目录的
路径中装载配置文件完成初始化工做 。从 WebApplicationContext 中能够得到
ServletContext 的引用, 整个 Web 应用上下文对象将做为属性放置到 ServletContext
中,以便 Web 应用环境能够访问 Spring 应用上下文
 

6.1.7.4. Spring Bean 做用域
Spring 3 中为 Bean 定义了 5 中做用域, 分别为 singleton(单例)、 prototype(原型)、
request、 session 和 global session, 5 种做用域说明以下:
singleton:单例模式(多线程下不安全)
1. singleton:单例模式, Spring IoC 容器中只会存在一个共享的 Bean 实例,不管有多少个
Bean 引用它,始终指向同一对象。 该模式在多线程下是不安全的。 Singleton 做用域是
Spring 中的缺省做用域,也能够显示的将 Bean 定义为 singleton 模式,配置为:
<bean id="userDao" class="com.ioc.UserDaoImpl" scope="singleton"/>
 

prototype:原型模式每次使用时建立
2. prototype:原型模式,每次经过 Spring 容器获取 prototype 定义的 bean 时,容器都将建立
一个新的 Bean 实例,每一个 Bean 实例都有本身的属性和状态,而 singleton 全局只有一个对
象。根据经验, 对有状态的bean使用prototype做用域,而对无状态的bean使用singleton
做用域
 

Request:一次 request 一个实例
3. request:在一次 Http 请求中,容器会返回该 Bean 的同一实例。而对不一样的 Http 请求则会
产生新的 Bean,并且该 bean 仅在当前 Http Request 内有效,当前 Http 请求结束,该 bean
实例也将会被销毁。
<bean id="loginAction" class="com.cnblogs.Login" scope="request"/>
 

session
4. session:在一次 Http Session 中,容器会返回该 Bean 的同一实例。而对不一样的 Session 请
求则会建立新的实例,该 bean 实例仅在当前 Session 内有效。 同 Http 请求相同,每一次
session 请求建立新的实例,而不一样的实例之间不共享属性,且实例仅在本身的 session 请求
内有效,请求结束,则实例将被销毁。
<bean id="userPreference" class="com.ioc.UserPreference" scope="session"/>

global Session
5. global Session:在一个全局的 Http Session 中,容器会返回该 Bean 的同一个实例,仅在
使用 portlet context 时有效
 

6.1.7.5. Spring Bean 生命周期
实例化
1. 实例化一个 Bean, 也就是咱们常说的 new。
IOC 依赖注入
2. 按照 Spring 上下文对实例化的 Bean 进行配置, 也就是 IOC 注入。
setBeanName 实现
3. 若是这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String)
方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值
BeanFactoryAware 实现
4. 若是这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory,
setBeanFactory(BeanFactory)传递的是 Spring 工厂自身(能够用这个方式来获取其它 Bean,
只需在 Spring 配置文件中配置一个普通的 Bean 就能够)。
 

ApplicationContextAware 实现
5. 若是这个 Bean 已经实现了 ApplicationContextAware 接口,会调用
setApplicationContext(ApplicationContext)方法,传入 Spring 上下文(一样这个方式也
能够实现步骤 4 的内容,但比 4 更好,由于 ApplicationContext 是 BeanFactory 的子接
口,有更多的实现方法)
 

postProcessBeforeInitialization 接口实现-初始化预处理
6. 若是这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postProcessBeforeInitialization(Object obj, String s)方法, BeanPostProcessor 常常被用
做是 Bean 内容的更改,而且因为这个是在 Bean 初始化结束时调用那个的方法,也能够被应
用于内存或缓存技术。
init-method
7. 若是 Bean 在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始化方法
 

postProcessBeforeInitialization 接口实现-初始化预处理
6. 若是这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postProcessBeforeInitialization(Object obj, String s)方法, BeanPostProcessor 常常被用
做是 Bean 内容的更改,而且因为这个是在 Bean 初始化结束时调用那个的方法,也能够被应
用于内存或缓存技术。
init-method
7. 若是 Bean 在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始化方法。
postProcessAfterInitialization
8. 若是这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postProcessAfterInitialization(Object obj, String s)方法。
注: 以上工做完成之后就能够应用这个 Bean 了,那这个 Bean 是一个 Singleton 的,因此一
般状况下咱们调用同一个 id 的 Bean 会是在内容地址相同的实例,固然在 Spring 配置文件中
也能够配置非 Singleton
 

Destroy 过时自动清理阶段
9. 当 Bean 再也不须要时,会通过清理阶段,若是 Bean 实现了 DisposableBean 这个接口,会调
用那个其实现的 destroy()方法;
destroy-method 自配置清理
10. 最后,若是这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的
销毁方法
 

11. bean 标签有两个重要的属性(init-method 和 destroy-method)。用它们你能够本身定制
初始化和注销方法。它们也有相应的注解(@PostConstruct 和@PreDestroy) 。
<bean id="" class="" init-method="初始化方法" destroy-method="销毁方法">
 

6.1.7.6. Spring 依赖注入四种方式
构造器注入

/*带参数,方便利用构造器进行注入*/
public CatDaoImpl(String message){
this. message = message;
}
<bean id="CatDaoImpl" class="com.CatDaoImpl">
<constructor-arg value=" message "></constructor-arg>
</bean

 

setter 方法注入

public class Id {
private int id;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
}
<bean id="id" class="com.id "> <property name="id" value="123"></property> </bean>

 

静态工厂注入
静态工厂顾名思义,就是经过调用静态工厂的方法来获取本身须要的对象,为了让 spring 管理所
有对象,咱们不能直接经过"工程类.静态方法()"来获取对象,而是依然经过 spring 注入的形式获
取:

public class DaoFactory { //静态工厂
public static final FactoryDao getStaticFactoryDaoImpl(){
return new StaticFacotryDaoImpl();
}
}
public class SpringAction {
private FactoryDao staticFactoryDao; //注入对象
//注入对象的 set 方法
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
this.staticFactoryDao = staticFactoryDao;
}
}
//factory-method="getStaticFactoryDaoImpl"指定调用哪一个工厂方法
<bean name="springAction" class=" SpringAction" >
<!--使用静态工厂的方法注入对象,对应下面的配置文件-->
<property name="staticFactoryDao" ref="staticFactoryDao"></property>
</bean>
<!--此处获取对象的方式是从工厂类中获取静态方法-->
<bean name="staticFactoryDao" class="DaoFactory"
factory-method="getStaticFactoryDaoImpl"></bean>

 

实例工厂
实例工厂的意思是获取对象实例的方法不是静态的,因此你须要首先 new 工厂类,再调用普通的
实例方法:

public class DaoFactory { //实例工厂
public FactoryDao getFactoryDaoImpl(){
return new FactoryDaoImpl();


13/04/2018 Page 128 of 283

}
}
public class SpringAction {
private FactoryDao factoryDao; //注入对象
public void setFactoryDao(FactoryDao factoryDao) {
this.factoryDao = factoryDao;
}
}
<bean name="springAction" class="SpringAction">
<!--使用实例工厂的方法注入对象,对应下面的配置文件-->
<property name="factoryDao" ref="factoryDao"></property>
</bean>
<!--此处获取对象的方式是从工厂类中获取实例方法-->
<bean name="daoFactory" class="com.DaoFactory"></bean>
<bean name="factoryDao" factory-bean="daoFactory"
factory-method="getFactoryDaoImpl"></bean>

6.1.7.7. 5 种不一样方式的自动装配
Spring 装配包括手动装配和自动装配,手动装配是有基于 xml 装配、 构造方法、 setter 方法等
自动装配有五种自动装配的方式,能够用来指导 Spring 容器用自动装配方式来进行依赖注入。
1. no:默认的方式是不进行自动装配,经过显式设置 ref 属性来进行装配。
2. byName:经过参数名 自动装配, Spring 容器在配置文件中发现 bean 的 autowire 属性被设
置成 byname,以后容器试图匹配、装配和该 bean 的属性具备相同名字的 bean。
3. byType:经过参数类型自动装配, Spring 容器在配置文件中发现 bean 的 autowire 属性被
设置成 byType,以后容器试图匹配、装配和该 bean 的属性具备相同类型的 bean。若是有多
个 bean 符合条件,则抛出错误。
4. constructor:这个方式相似于 byType, 可是要提供给构造器参数,若是没有肯定的带参数
的构造器参数类型,将会抛出异常。
5. autodetect:首先尝试使用 constructor 来自动装配,若是没法工做,则使用 byType 方式。
 

 

6.1.8. Spring AOP 原理
6.1.8.1. 概念
"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,
并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共
同调用的逻辑或责任封装起来,便于减小系统的重复代码,下降模块之间的耦合度,并有利于未
来的可操做性和可维护性。
使用"横切"技术, AOP 把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流
程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特色是,他们常常发生
在核心关注点的多处,而各处基本类似, 好比权限认证、日志、事物。 AOP 的做用在于分离系统
中的各类关注点,将核心关注点和横切关注点分离开来

 

AOP 主要应用场景有:
1. Authentication 权限
2. Caching 缓存
3. Context passing 内容传递
4. Error handling 错误处理
5. Lazy loading 懒加载
6. Debugging 调试
7. logging, tracing, profiling and monitoring 记录跟踪 优化 校准
8. Performance optimization 性能优化
9. Persistence 持久化
10. Resource pooling 资源池
11. Synchronization 同步
12. Transactions 事务
 

6.1.8.2. AOP 核心概念
一、切面(aspect) : 类是对物体特征的抽象,切面就是对横切关注点的抽象
二、横切关注点: 对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点。
三、链接点(joinpoint) : 被拦截到的点,由于 Spring 只支持方法类型的链接点,因此在 Spring
中链接点指的就是被拦截到的方法,实际上链接点还能够是字段或者构造器。
四、切入点(pointcut) : 对链接点进行拦截的定义
五、通知(advice) : 所谓通知指的就是指拦截到链接点以后要执行的代码, 通知分为前置、后置、
异常、最终、环绕通知五类。
六、目标对象: 代理的目标对象
七、织入(weave) : 将切面应用到目标对象并致使代理对象建立的过程

八、引入(introduction) : 在不修改代码的前提下,引入能够在运行期为类动态地添加一些方法
或字段。
 

6.1.8.1. AOP 两种代理方式
Spring 提供了两种方式来生成代理对象: JDKProxy 和 Cglib,具体使用哪一种方式 生成由
AopProxyFactory 根据 AdvisedSupport 对象的配置来决定。 默认的策略是若是目标类是接口,
则使用 JDK 动态代理技术,不然使用 Cglib 来生成代理。
JDK 动态接口代理
1. JDK 动态代理主要涉及到 java.lang.reflect 包中的两个类: Proxy 和 InvocationHandler。
InvocationHandler 是一个接口,经过实现该接口定义横切逻辑,并经过反射机制调用目标类
的代码,动态将横切逻辑和业务逻辑编制在一块儿。 Proxy 利用 InvocationHandler 动态建立
一个符合某一接口的实例,生成目标类的代理对象。
 

CGLib 动态代理
2. : CGLib 全称为 Code Generation Library,是一个强大的高性能, 高质量的代码生成类库,
能够在运行期扩展 Java 类与实现 Java 接口, CGLib 封装了 asm,能够再运行期动态生成新
的 class。和 JDK 动态代理相比较: JDK 建立代理有一个限制,就是只能为接口建立代理实例,
而对于没有经过接口定义业务方法的类,则能够经过 CGLib 建立动态代理。
 

CGLib 动态代理
2. : CGLib 全称为 Code Generation Library,是一个强大的高性能, 高质量的代码生成类库,
能够在运行期扩展 Java 类与实现 Java 接口, CGLib 封装了 asm,能够再运行期动态生成新
的 class。和 JDK 动态代理相比较: JDK 建立代理有一个限制,就是只能为接口建立代理实例,
而对于没有经过接口定义业务方法的类,则能够经过 CGLib 建立动态代理。
 

6.1.8.2. 实现原理

@Aspect
public class TransactionDemo {
@Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))")
public void point(){
}
@Before(value="point()")
public void before(){
System.out.println("transaction begin");
}
@AfterReturning(value = "point()")
public void after(){
System.out.println("transaction commit");
}
@Around("point()")
public void around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("transaction begin");
joinPoint.proceed();
System.out.println("transaction commit");
}
}

 

6.1.9. Spring MVC 原理
Spring 的模型-视图-控制器(MVC)框架是围绕一个 DispatcherServlet 来设计的,这个 Servlet
会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染
等,甚至还能支持文件上传。

 

 

 

6.1.10. Spring Boot 原理
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭
建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员再也不须要定义样板化的
配置。经过这种方式, Spring Boot 致力于在蓬勃发展的快速应用开发领域(rapid application
development)成为领导者。 其特色以下:
1. 建立独立的 Spring 应用程序
2. 嵌入的 Tomcat,无需部署 WAR 文件
3. 简化 Maven 配置
4. 自动配置 Spring
5. 提供生产就绪型功能,如指标,健康检查和外部配置
6. 绝对没有代码生成和对 XML 没有要求配置 [1]
 

 

6.1.11. JPA 原理
6.1.11.1. 事务
事务是计算机应用中不可或缺的组件模型,它保证了用户操做的原子性 ( Atomicity )、一致性
( Consistency )、隔离性 ( Isolation ) 和持久性 ( Durabilily )。
6.1.11.2. 本地事务
紧密依赖于底层资源管理器(例如数据库链接 ),事务处理局限在当前事务资源内。此种事务处理
方式不存在对应用服务器的依赖,于是部署灵活却没法支持多数据源的分布式事务。在数据库连
接中使用本地事务

 

6.1.11.1. 分布式事务
Java 事务编程接口(JTA: Java Transaction API)和 Java 事务服务 (JTS; Java Transaction
Service) 为 J2EE 平台提供了分布式事务服务。分布式事务(Distributed Transaction)包括事务
管理器( Transaction Manager)和一个或多个支持 XA 协议的资源管理器 ( Resource
Manager )。咱们能够将资源管理器看作任意类型的持久化数据存储;事务管理器承担着全部事务
参与单元的协调与控制
 

6.1.11.1. 两阶段提交
两阶段提交主要保证了分布式事务的原子性:即全部结点要么全作要么全不作,所谓的两个阶段
是指: 第一阶段:准备阶段;第二阶段:提交阶段
 

1 准备阶段
事务协调者(事务管理器)给每一个参与者(资源管理器)发送 Prepare 消息,每一个参与者要么直接返回
失败(如权限验证失败), 要么在本地执行事务,写本地的 redo 和 undo 日志,但不提交, 到达一
种“万事俱备,只欠东风”的状态。
2 提交阶段:
若是协调者收到了参与者的失败消息或者超时,直接给每一个参与者发送回滚(Rollback)消息;不然,
发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操做,释放全部事务处理过
程中使用的锁资源。 (注意:必须在最后阶段释放锁资源)
 

将提交分红两阶段进行的目的很明确,就是尽量晚地提交事务,让事务在提交前尽量地完成
全部能完成的工做
 

6.1.12. Mybatis 缓存
Mybatis 中有一级缓存和二级缓存,默认状况下一级缓存是开启的,并且是不能关闭的。一级缓存
是指 SqlSession 级别的缓存,当在同一个 SqlSession 中进行相同的 SQL 语句查询时,第二次以
后的查询不会从数据库查询,而是直接从缓存中获取,一级缓存最多缓存 1024 条 SQL。二级缓存
是指能够跨 SqlSession 的缓存。 是 mapper 级别的缓存,对于 mapper 级别的缓存不一样的
sqlsession 是能够共享的

 

 

6.1.12.1. Mybatis 的一级缓存原理(sqlsession 级别)
第一次发出一个查询 sql, sql 查询结果写入 sqlsession 的一级缓存中,缓存使用的数据结构是一
个 map。
key: MapperID+offset+limit+Sql+全部的入参
value:用户信息
同一个 sqlsession 再次发出相同的 sql,就从缓存中取出数据。若是两次中间出现 commit 操做
(修改、添加、删除),本 sqlsession 中的一级缓存区域所有清空,下次再去缓存中查询不到所
以要从数据库查询, 从数据库查询到再写入缓存
 

6.1.12.2. 二级缓存原理(mapper 基本)
二级缓存的范围是 mapper 级别(mapper 同一个命名空间), mapper 以命名空间为单位建立缓
存数据结构,结构是 map。 mybatis 的二级缓存是经过 CacheExecutor 实现的。 CacheExecutor
13/04/2018 Page 139 of 283
实际上是 Executor 的代理对象。全部的查询操做,在 CacheExecutor 中都会先匹配缓存中是否存
在,不存在则查询数据库。
key: MapperID+offset+limit+Sql+全部的入参
具体使用须要配置
 

具体使用须要配置:
1. Mybatis 全局配置中启用二级缓存配置
2. 在对应的 Mapper.xml 中配置 cache 节点
3. 在对应的 select 查询节点中添加 useCache=true
 

6.1.13. Tomcat 架构
http://www.importnew.com/21112.html
 

7. 微服务
7.1.1. 服务注册发现
服务注册就是维护一个登记簿,它管理系统内全部的服务地址。当新的服务启动后,它会向登记
簿交待本身的地址信息。服务的依赖方直接向登记簿要 Service Provider 地址就好了。当下用于服
务注册的工具很是多 ZooKeeper, Consul, Etcd, 还有 Netflix 家的 eureka 等。 服务注册有两种
形式:客户端注册和第三方注册。
7.1.1.1. 客户端注册(zookeeper)
客户端注册是服务自身要负责注册与注销的工做。当服务启动后向注册中心注册自身,当服务下
线时注销本身。期间还须要和注册中心保持心跳。心跳不必定要客户端来作,也能够由注册中心
负责(这个过程叫探活)。这种方式的缺点是注册工做与服务耦合在一块儿,不一样语言都要实现一
套注册逻辑。
 

7.1.1.1. 客户端注册(zookeeper)
客户端注册是服务自身要负责注册与注销的工做。当服务启动后向注册中心注册自身,当服务下
线时注销本身。期间还须要和注册中心保持心跳。心跳不必定要客户端来作,也能够由注册中心
负责(这个过程叫探活)。这种方式的缺点是注册工做与服务耦合在一块儿,不一样语言都要实现一
套注册逻辑。

7.1.1.2. 第三方注册(独立的服务 Registrar)
第三方注册由一个独立的服务Registrar负责注册与注销。当服务启动后以某种方式通知Registrar,
而后 Registrar 负责向注册中心发起注册工做。同时注册中心要维护与服务之间的心跳,当服务不
可用时,向注册中心注销服务。这种方式的缺点是 Registrar 必须是一个高可用的系统,不然注册
工做无法进展。
 

7.1.1.3. 客户端发现
客户端发现是指客户端负责查询可用服务地址,以及负载均衡的工做。这种方式最方便直接,而
且也方便作负载均衡。再者一旦发现某个服务不可用当即换另一个,很是直接。缺点也在于多
语言时的重复工做,每一个语言实现相同的逻辑。
 

7.1.1.4. 服务端发现
服务端发现须要额外的 Router 服务,请求先打到 Router,而后 Router 负责查询服务与负载均衡。
这种方式虽然没有客户端发现的缺点,可是它的缺点是保证 Router 的高可用
 

7.1.1.5. Consul
7.1.1.6. Eureka
7.1.1.7. SmartStack
7.1.1.8. Etcd

 

7.1.2. API 网关
API Gateway 是一个服务器,也能够说是进入系统的惟一节点。这跟面向对象设计模式中的
Facade 模式很像。 API Gateway 封装内部系统的架构,而且提供 API 给各个客户端。它还可能有
其余功能,如受权、监控、负载均衡、缓存、请求分片和管理、静态响应处理等。下图展现了一
个适应当前架构的 API Gateway
 

API Gateway 负责请求转发、合成和协议转换。全部来自客户端的请求都要先通过 API Gateway,
而后路由这些请求到对应的微服务。 API Gateway 将常常经过调用多个微服务来处理一个请求以
及聚合多个服务的结果。它能够在 web 协议与内部使用的非 Web 友好型协议间进行转换,如
HTTP 协议、 WebSocket 协议。
 

7.1.2.1. 请求转发
服务转发主要是对客户端的请求安装微服务的负载转发到不一样的服务上
7.1.2.2. 响应合并
把业务上须要调用多个服务接口才能完成的工做合并成一次调用对外统一提供服务。
7.1.2.3. 协议转换
重点是支持 SOAP, JMS, Rest 间的协议转换。
7.1.2.4. 数据转换
重点是支持 XML 和 Json 之间的报文格式转换能力(可选)
13/04/2018 Page 144 of 283
7.1.2.5. 安全认证
1. 基于 Token 的客户端访问控制和安全策略
2. 传输数据和报文加密,到服务端解密,须要在客户端有独立的 SDK 代理包
3. 基于 Https 的传输加密,客户端和服务端数字证书支持
4. 基于 OAuth2.0 的服务安全认证(受权码,客户端,密码模式等)
 

 

7.1.3. 配置中心
配置中心通常用做系统的参数配置,它须要知足以下几个要求:高效获取、实时感知、分布式访
问。
7.1.3.1. zookeeper 配置中心
实现的架构图以下所示,采起数据加载到内存方式解决高效获取的问题,借助 zookeeper 的节点
监听机制来实现实时感知。
 

7.1.4. 事件调度(kafka)
消息服务和事件的统一调度,经常使用用 kafka , activemq 等
 

7.1.5. 服务跟踪(starter-sleuth)
随着微服务数量不断增加,须要跟踪一个请求从一个微服务到下一个微服务的传播过程, Spring
Cloud Sleuth 正是解决这个问题,它在日志中引入惟一 ID,以保证微服务调用之间的一致性,这
样你就能跟踪某个请求是如何从一个微服务传递到下一个。
 

1. 为了实现请求跟踪,当请求发送到分布式系统的入口端点时,只须要服务跟踪框架为该请求
建立一个惟一的跟踪标识,同时在分布式系统内部流转的时候,框架始终保持传递该惟一标
识,直到返回给请求方为止, 这个惟一标识就是前文中提到的 Trace ID。经过 Trace ID 的记
录,咱们就能将全部请求过程日志关联起来。
2. 为了统计各处理单元的时间延迟,当请求达到各个服务组件时,或是处理逻辑到达某个状态
时,也经过一个惟一标识来标记它的开始、具体过程以及结束,该标识就是咱们前文中提到
的 Span ID, 对于每一个 Span 来讲,它必须有开始和结束两个节点,经过记录开始 Span 和结
束 Span 的时间戳,就能统计出该 Span 的时间延迟,除了时间戳记录以外,它还能够包含一
些其余元数据,好比:事件名称、请求信息等。
3. 在快速入门示例中,咱们轻松实现了日志级别的跟踪信息接入,这彻底归功于spring-cloudstarter-sleuth 组件的实现。在 Spring Boot 应用中,经过在工程中引入 spring-cloudstarter-sleuth 依赖以后, 它会自动的为当前应用构建起各通讯通道的跟踪机制,好比:
 经过诸如 RabbitMQ、 Kafka(或者其余任何 Spring Cloud Stream 绑定器实现的消息
中间件)传递的请求。
 经过 Zuul 代理传递的请求。
 经过 RestTemplate 发起的请求。
 

7.1.6. 服务熔断(Hystrix)
在微服务架构中一般会有多个服务层调用,基础服务的故障可能会致使级联故障,进而形成整个
系统不可用的状况,这种现象被称为服务雪崩效应。服务雪崩效应是一种因“服务提供者”的不
可用致使“服务消费者”的不可用,并将不可用逐渐放大的过程。
熔断器的原理很简单,如同电力过载保护器。它能够实现快速失败,若是它在一段时间内侦测到
许多相似的错误, 会强迫其之后的多个调用快速失败,再也不访问远程服务器,从而防止应用程序
不断地尝试执行可能会失败的操做,使得应用程序继续执行而不用等待修正错误,或者浪费 CPU
时间去等到长时间的超时产生。熔断器也可使应用程序可以诊断错误是否已经修正,若是已经
修正,应用程序会再次尝试调用操做
 

7.1.6.1. Hystrix 断路器机制
断路器很好理解, 当 Hystrix Command 请求后端服务失败数量超过必定比例(默认 50%), 断路器会
切换到开路状态(Open). 这时全部请求会直接失败而不会发送到后端服务. 断路器保持在开路状态
一段时间后(默认 5 秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回状况,
若是请求成功, 断路器切回闭路状态(CLOSED), 不然从新切换到开路状态(OPEN). Hystrix 的断路器
就像咱们家庭电路中的保险丝, 一旦后端服务不可用, 断路器会直接切断请求链, 避免发送大量无效
请求影响系统吞吐量, 而且断路器有自我检测并恢复的能力。
 

7.1.7. API 管理
SwaggerAPI 管理工具。

http://www.javashuo.com/article/p-kzbuvdhv-do.html8

相关文章
相关标签/搜索