(一)Spring IoC
重要概念
1, 控制反转(Inversion of control):
控制反转是一种通过描述 (在 java 中通过 xml 或者注解) 并通过第三方去产生或获取特定对象的方式.
控制反转 IoC(Inversion of Control)是说创建对象的控制权进行转移, 以前创建对象的主动权和创建时机是由自己把控的, 而现在这种权力转移到第三方, 比如转移交给了 IoC 容器, 它就是一个专门用来创建对象的工厂, 你要什么对象, 它就给你什么对象, 有了 IoC 容器, 依赖关系就变了, 原先的依赖关系就没了, 它们都依赖 IoC 容器了, 通过 IoC 容器来建立它们之间的关系.
控制反转就是获取依赖对象的方式反转了, 正常情况下由应用程序主动创建依赖对象, 实现对依赖对象的管理, 创建依赖对象的控制权在应用程序手中, 应用程序需要什么对象, 就主动去创建这个对象, 这是正转的情况. 实现控制反转之后, 由 IoC 容器实现依赖对象的创建和管理, 应用程序需要什么样的对象, IoC 容器就根据需求创建这个对象, 应用程序只是被动地接收和使用这个对象, 依赖对象的创建管理控制权由应用程序转移给了 IoC 容器, 这就实现了控制反转.
2, 依赖注入(Dependency Injection):
控制反转的另一种表述方式, 即让调用类对某一接口的实现类的依赖关系由第三方 (容器或协作类) 注入, 用以移除调用类对某一接口实现类的依赖.
3,Beanfacory 和 ApplicationContext:
Spring 通过配置文件描述 Bean 以及 Bean 之间的依赖关系, 利用 Java 语言的反射功能实例化 Bean 并建立起 Bean 之间的依赖关系. Spring 的 IoC 容器在完成这些底层工作的基础上, 提供了 Bean 实例缓存, 生命周期管理, Bean 实例代理, 事件发布, 资源装载等服务.
Beanfacory 是 Spring 框架最核心的接口, 提供了高级 IoC 的配置机制. Beanfacory 使管理不同的 java 对象成为可能, ApplicationContext(应用上下文)建立在 Beanfacory 基础之上, 提供更多面向引用的功能. Beanfacory 即为 IoC 容器, 由于 ApplicationContext 建立在 Beanfacory, 我们也称 ApplicationContext 为 IoC 容器.
IoC 容器主要功能
1, 动态创建, 注入依赖对象.
2, 管理对象生命周期.
3, 映射依赖关系.
实现 IoC 容器的方式:
1, 依赖查找.
2, 依赖注入.
依赖注入的三种方式: 1, 构造器注入. 2,setter 注入. 3, 接口注入.
注入和装配的区别:
注入是实例化一个类时对类中各个参数的赋值方式.
装配是定义 bean 以及 bean 之间关系.
装配 bean 概述:
1, 基于 xml 中配置.
2, 基于注解中配置.
3, 基于 java 类配置.
4, 基于 Groovy DSL 配置.
Bean 作用域:
1, 单例(singleton): 它是默认的选项, 在整个应用中, Spring 只为其生成一个 Bean 的实例.
2, 原型(prototype): 每次注入时, 或者通过 Spring IoC 容器获取 Bean 时, Spring 都会为它创建一个新的实例.
3, 会话(session): 在 web 应用中使用, 就是在会话过程中 Spring 只会创建一个实例.
4, 请求(request): 在 Web 应用中使用, 就是在一次请求中 Spring 会创建一个实例, 但是不同的请求会创建不同的实例.
基于 xml 中配置
1, 四种自动装配类型:
(1)byName: 根据名字自行自动匹配.
(2)byType: 根据类型自行自动匹配.
(3)construtor: 根据构造函数自行自动匹配.
(4)autodetect: 根据 bean 的自省机制选择 byType 或者 construtor.
2,Bean 之间的关系:
(1)继承;(2)依赖;(3)引用.
基于注解的配置
1, 使用注解定义 bean
@Component: 用于对所有的类进行注解.
@Repository: 用于对 Dao 实现类进行标注.
@Service: 用于对 Service 实现类进行标注.
@controller: 用于对 controller 实现类进行标注.
2, 自动装配
(1)@Autowired: 通过 @Autowired 注解实现 Bean 的依赖注入.
(2)@Autowired 的 required 属性: 用来指定是否必须找到匹配的 Bean.
(3)@Qualifier, 指定 Bean 的名称.
profile: 用于切换开发环境.
Spring EL:
概念: 更为灵活的注入方式, 能够在运行时构建复杂表达式, 存取对象属性, 对象方法调用等.
作用:
1, 使用 bean id 引用 bean.
2, 调用指定对象的方法和访问对象的属性.
3, 进行运算.
4, 提供正则表达式进行匹配.
5, 集合配置.
(二)面向切面编程(Aspect Oriented Programming)
概述: AOP 技术利用 "横切" 技术, 剖解开封装的对象内部, 并将那些影响了多个类的公共行为封装到一个可重用模块, 并将其命名为 "Aspect", 即切面. 所谓 "切面", 简单说就是那些与业务无关, 却为业务模块所共同调用的逻辑或责任封装起来, 便于减少系统的重复代码, 降低模块之间的耦合度, 并有利于未来的可操作性和可维护性.
AOP 相关概念
1, 方面(Aspect): 一个关注点的模块化, 这个关注点实现可能另外横切多个对象. 事务管理是 J2EE 应用中一个很好的横切关注点例子. 方面用 Spring 的 Advisor 或拦截器实现.
2, 连接点(Joinpoint): 程序执行过程中明确的点, 如方法的调用或特定的异常被抛出.
3, 通知(Advice): 在特定的连接点, AOP 框架执行的动作. 各种类型的通知包括 "around","before" 和 "throws" 通知. 通知类型将在下面讨论. 许多 AOP 框架包括 Spring 都是以拦截器做通知模型, 维护一个 "围绕" 连接点的拦截器链. Spring 中定义了四个 advice: BeforeAdvice, AfterAdvice, ThrowAdvice 和 DynamicIntroductionAdvice.
4, 切入点(Pointcut): 指定一个通知将被引发的一系列连接点的集合. AOP 框架必须允许开发者指定切入点: 例如, 使用正则表达式. Spring 定义了 Pointcut 接口, 用来组合 MethodMatcher 和 ClassFilter, 可以通过名字很清楚的理解, MethodMatcher 是用来检查目标类的方法是否可以被应用此通知, 而 ClassFilter 是用来检查 Pointcut 是否应该应用到目标类上.
5, 引入(Introduction): 添加方法或字段到被通知的类. Spring 允许引入新的接口到任何被通知的对象. 例如, 你可以使用一个引入使任何对象实现 IsModified 接口, 来简化缓存. Spring 中要使用 Introduction, 可有通过 DelegatingIntroductionInterceptor 来实现通知, 通过 DefaultIntroductionAdvisor 来配置 Advice 和代理类要实现的接口.
6, 目标对象(Target Object): 包含连接点的对象. 也被称作被通知或被代理对象. POJO.
7,AOP 代理(AOP Proxy): AOP 框架创建的对象, 包含通知. 在 Spring 中, AOP 代理可以是 JDK 动态代理或者 CGLIB 代理.
8, 织入(Weaving): 组装方面来创建一个被通知对象. 这可以在编译时完成(例如使用 AspectJ 编译器), 也可以在运行时完成. Spring 和其他纯 Java AOP 框架一样, 在运行时完成织入.
前置通知 (Before advice): 在某连接点(join point) 之前执行的通知, 但这个通知不能阻止连接点前的执行(除非它抛出一个异常).
后置通知(After advice): 当某连接点退出的时候执行的通知(不论是正常返回还是异常退出).
环绕通知 (Around Advice): 包围一个连接点(join point) 的通知, 如方法调用. 这是最强大的一种通知类型. 环绕通知可以在方法调用前后完成自定义的行为. 它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行.
返回后通知 (After returning advice): 在某连接点(join point) 正常完成后执行的通知, 例如, 一个方法没有抛出任何异常, 正常返回.
抛出异常后通知(After throwing advice): 在方法抛出异常退出时执行的通知.
Spring AOP 实现的四种方式:
1, 使用 proxyFactoryBean 和对应的接口实现 AOP
2, 使用 xml 配置 AOP
3, 使用 @AspectJ 注解驱动切面
4, 使用 AspectJ 注入切面
多切面的情况:
(1)aspect 里面有一个 order 属性, order 属性的数字就是横切关注点的顺序.
(2)Spring 默认以 aspect 的定义顺序作为织入顺序.
(三)Spring 事务管理
1, 事务管理器
Spring 并不直接管理事务, 而是提供了多种事务管理器, 他们将事务管理的职责委托给 Hibernate 或者 JTA 等持久化机制所提供的相关平台框架的事务来实现. Spring 事务管理器的接口是 org.springframework.transaction.PlatformTransactionManager, 通过这个接口, Spring 为各个平台如 JDBC,Hibernate 等都提供了对应的事务管理器.
2, 事务属性的定义
(1)传播行为:
Spring 定义了七种传播行为, 以下为常见类型:
PROPAGATION_REQUIRED: 表示当前方法必须运行在事务中. 如果当前事务存在, 方法将会在该事务中运行. 否则, 会启动一个新的事务
PROPAGATION_SUPPORTS: 表示当前方法不需要事务上下文, 但是如果存在当前事务的话, 那么该方法会在这个事务中运行
PROPAGATION_MANDATORY: 表示该方法必须在事务中运行, 如果当前事务不存在, 则会抛出一个异常
(2)隔离级别
隔离级别定义了一个事务可能受其他并发事务影响的程度.
ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别
ISOLATIONREADUNCOMMITTED: 最低的隔离级别, 允许读取尚未提交的数据变更, 可能会导致脏读, 幻读或不可重复读.
ISOLATIONREADCOMMITTED: 允许读取并发事务已经提交的数据, 可以阻止脏读, 但是幻读或不可重复读仍有可能发生
ISOLATIONREPEATABLEREAD: 对同一字段的多次读取结果都是一致的, 除非数据是被本身事务自己所修改, 可以阻止脏读和不可重复读, 但幻读仍有可能发生
ISOLATION_SERIALIZABLE: 最高的隔离级别, 完全服从 ACID 的隔离级别, 确保阻止脏读, 不可重复读以及幻读, 也是最慢的事务隔离级别, 因为它通常是通过完全锁定事务相关的数据库表来实现的
(3)只读: 通过将事务设置为只读, 你就可以给数据库一个机会, 让它应用它认为合适的优化措施.
(4)事务超时: 事务超时就是事务的一个定时器, 在特定时间内事务如果没有执行完毕, 那么就会自动回滚, 而不是一直等待其结束.
(5)回滚规则: 这些规则定义了哪些异常会导致事务回滚而哪些不会.
3, 编程式和声明式事务的区别
Spring 提供了对编程式事务和声明式事务的支持, 编程式事务允许用户在代码中精确定义事务的边界, 而声明式事务 (基于 AOP) 有助于用户将操作与事务规则进行解耦.
简单地说, 编程式事务侵入到了业务代码里面, 但是提供了更加详细的事务管理; 而声明式事务由于基于 AOP, 所以既能起到事务管理的作用, 又可以不影响业务代码的具体实现.
宜信技术学院 http://college.creditease.cn/#/index 作者: 姚远
来源: https://juejin.im/post/5c7654e351882562962ef70e