| 好处 | 说明 |
|---|---|
| 轻量 | 轻量的,基本的版本大约2MB。 |
| 控制反转IoC | 通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。 |
| 面向切面的编程(AOP) | 支持面向切面的编程,并且把应用业务逻辑和系统服务分开。 |
| 容器 | 包含并管理应用中对象的生命周期和配置。 |
| MVC框架 | Web框架是个精心设计的框架,是 Web框架的一个很好的替代品。 |
| 事务管理 | 提供一个持续的事务管理接口,可以扩展到 上至本地事务 下至全局事务(JTA)。 |
| 异常处理 | 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常 |
A 表现层 web层 —— MVC是表现层的一个设计模型
B 业务层 service层
C 持久层 dao层
IOC = inversion of control 控制反转。
借助ioc容器实现具有依赖关系的对象之间的解耦。
作用
在于解耦,可以解除对象之间的耦合,让对象和对象之间完全没有联系,这样完成或修改一个对象时不需要考虑其他对象。
出现原因
java是面向对象的语言,应用程序需要通过一个个对象之间的关联和作用来完成功能。
这样对象之间紧密的咬合形成的系统会具有较高的耦合度。导致一个对象出现问题,整个系统无法工作。
加入ioc容器,会使得对象之间的耦合性降低,修改一个对象不会对其他对象造成影响。
原理
没有ioc容器的时候,对象A依赖对象B,A在运行到某一时刻的时候回去创建B的对象,这样A具有主动权,它控制了对象B的创建;
引入ioc以后对象A和对象B之间就没有直接的联系,当对象A运行的时候由ioc容器创建B对象在适当的时候注入到对象A中,
这样对象B的控制权就由A对象转移到了ioc容器。
控制反转是一种设计思想,依赖注入是该思想的具体实现。
例子:(创建userServiceImpl类中,有UserDao类的对象)
控制反转 = 将创建UserDao类的userDaoImpl对象的控制反转过来由userServiceImpl类交给ioc容器,强调的是一种能力和思想;
依赖注入 = ioc容器将UserServiceImpl所依赖的userDaoImpl,注入给userServiceImpl,强调的是一个过程和实现。
在 Spring 中,构成应用程序主干 并由Spring IoC容器 管理的对象称为bean。
bean是一个由Spring IoC容器实例化、组装和管理的对象。
理解:
bean是一个对象,一个或多个;
bean由spring ioc容器管理;
bean是应用程序的主干,也就是程序由bean组成;
spring容器会自动完成对@bean对象的实例化。
创建应用程序对象之间的协作关系的行为称为:装配(wiring)、即依赖注入的本质。
分为四个阶段:
实例化(Instantiation)
属性设置(populate)
初始化(initialization)
销毁(destruction)
传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。
AOP(Aspect-Oriented Programming)面向方面编程。
概念
Spring AOP 是基于 AOP 编程模式的一个框架,它能够有效的减少系统间的重复代码,达到松耦合的目的。
它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。该模块 = 与业务无关,却把业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
出现原因
是对OOP(Object-Oriented Programming)面向对象编程的补充和完善。
OOP 引入封装、继承和多态性等概念来建立一种对象层次结构,用来模拟公共行为的一个集合。
OOP 允许定义从上到下的关系,但并不适合定义从左到右的关系。
例如日志功能,日志代码往往水平地散布在所有对象层次中,而与它所散布到对象的核心功能毫无关系。
这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在 OOP 设计中,它导致了大量代码的重复,而不利于各个模块的重用。
组成
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。
业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。
横切关注点的特点是,它们经常发生在核心关注点的多处,而各处都基本相似。比如:权限认证、日志、事务处理。
AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
作用
面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足。
利用AOP对业务逻辑的各个部分进行隔离,降低业务逻辑的耦合性,提高程序的可重用性和开发效率。
主要用于对同一对象层次的公用行为建模。
两种方式:静态代理(AspectJ)、动态代理(基于接口的JDK代理 、 基于继承的CGLIB动态代理)。
具体使用哪种方式生成由 AopProxyFactory 根据 AdvisedSupport 对象的配置来决定。默认的策略是如果目标类是接口,则使用 JDK 动态代理技术,否则使用 Cglib 来生成代理。
AspectJ
是静态代理的增强,所谓的静态代理就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强。
JDK动态代理
通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。
JDK动态代理的核心是InvocationHandler接口和Proxy类。
Spring默认的动态代理方式就是JDK动态代理。
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。
CGLIB(Code Generation Library)
是一个代码生成的类库,可以在运行时动态的生成某个类的子类。
CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
JDK动态代理
CGLIB代理
| 类型 | 说明 |
|---|---|
| 前置通知(Before advice) | 在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。 ApplicationContext 中在 < aop:aspect > 里面使用 < aop:before > 元素进行声明; |
| 后置通知(After advice) | 当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。 ApplicationContext 中在 < aop:aspect > 里面使用 < aop:after > 元素进行声明。 |
| 返回后通知(After return advice ) | 在某连接点正常完成后执行的通知,不包括抛出异常的情况。 ApplicationContext 中在 < aop:aspect > 里面使用 << after-returning >> 元素进行声明。 |
| 环绕通知(Around advice) | 包围一个连接点的通知,类似 Web 中 Servlet规范中的 Filter 的 doFilter 方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。 ApplicationContext 中在 < aop:aspect > 里面使用 < aop:around > 元素进行声明。 |
| 抛出异常后通知(After throwing advice) | 在方法抛出异常退出时执行的通知。 ApplicationContext 中在 < aop:aspect > 里面使用 < aop:after-throwing > 元素进行声明。 |