Spring
Spring是什么?干什么的?怎么用?
参考文章:https://blog.csdn.net/YKorey/article/details/80629291
Spring是什么?
1.是一个轻量级的开源框架,是为解决企业应用开发的复杂性而创建的;
2.是一个三层架构,也为J2EE应用程序开发提供集成的框架;
web层:Spring MVC;
业务层:Spring的IOC;
持久层:Spring的JDBC、ORM、等持久层框架
3.Spring的核心是:控制反转(ioc)和面向切面编程(aop);
IOC 控制反转
-
控制反转模式(也称依赖性介入),主要是不创建对象,但是描述创建它们的方式,在代码中不直接与对象和服务连接,但在配文件中描述哪一组件需要哪一个服务;
-
IOC的设计目标是与JavaBean组件一起使用
-
直接作用在功能的底层;
-
Spring里面最高级的抽象是BeanFactory(对应的是工厂模式);
BeanFactory有两种模式:单态、原型;
单态:查询时对具有特定名称的对象共享实例进行检索;eg:Singleton
原型:每次检索都会创建单独的对象(在每个用户都需要自己的对象时,原型模式是最适合的);
AOP面向切面编程
-
是oop(Object Oriented Programming,面向对象编程)的补充和完善
oop:引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的集合。
oop允许开发者定义纵向的关系,它导致了大量代码的重复,不利于各个模块的重用。
纵向:与核心功能有关联,opp
横向:与核心功能毫无关系。日志、安全性、异常处理等,散布在各处的无关代码,被称为横切(cross cutting)
-
AOP是和OOP相反的一种叫做"横切"的技术。将影响到多个类的公共行为都封装到一个可重用模块,这就是AOP中的A(Aspect,切面,与业务无关,主要是减少代码的复用)
-
横切把系统分为两个部分:核心关注点 (业务处理的主要流程) 和 横切关注点 (在核心关注点里的多出,各处基本相同);
-
AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来;
-
横切关注点:eg:对哪些方法进行拦截,拦截后的处理;
-
切面 :类是对物体特征的抽象,切面就是对横切关注点的抽象;
-
Spring中AOP代理由Spring的IoC容器负责生成、管理、依赖关系也由IoC容器负责管理(AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供;
-
Spring的代理默认使用java动态代理来创建AOP代理,这样可以为任何接口实例创建代理;
-
当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理;
CGLIB:就是一个强大的,高性能的代码生成库,主要通过 对字节码的操作为对象引入间接级别,以控制对象的访问);
AOP基本概念
Joinpoint(连接点)
被拦截到的每个点,spring中指被拦截到的每一个方法,spring aop一个连接点即代表一个方法的执行。
Pointcut(切入点)
对连接点进行拦截的定义(匹配规则定义 规定拦截哪些方法,对哪些方法进行处理),spring 有专门的表达式语言定义。
Advice(通知)
拦截到每一个连接点即(每一个方法)后所要做的操作
1. 前置通知 (前置增强)— before() 执行方法前通知
2. 返回通知(返回增强)— afterReturn 方法正常结束返回后的通知
3. 异常抛出通知(异常抛出增强)— afetrThrow()
4. 最终通知 — after 无论方法是否发生异常,均会执行该通知。
5. 环绕通知 — around 包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。
五大注解
@Before: 前置通知, 在方法执行之前执行;
@After: 后置通知, 在方法执行之后执行 ;
@AfterRunning: 返回通知, 在方法返回结果之后执行;
@AfterThrowing: 异常通知, 在方法抛出异常之后;
@Around: 环绕通知, 围绕着方法执行;
Aspect(切面)
切入点与通知的结合,决定了切面的定义,切入点定义了要拦截哪些类的哪些方法,通知则定义了拦截过方法后要做什么,切面则是横切关注点的抽象,与类相似,类是对物体特征的抽象,切面则是横切关注点抽象。
Target(目标对象)
被代理的目标对象
Weave(织入)
将切面应用到目标对象并生成代理对象的这个过程即为织入
Introduction(引入)
在不修改原有应用程序代码的情况下,在程序运行期为类动态添加方法或者字段的过程称为引入
注解式AOP实例
/**
* 切面
* 切入点和通知的抽象 (与面向对象中的 类 相似)
* 定义 切入点和通知 (切入点定义了要拦截哪些类的哪些方法,通知则定义了拦截过方法后要做什么)
*/
@Component // 将对象交给IOC容器去实例化
@Aspect // 声明当前类是一个切面
public class LogCut {
/**
* 切入点:
* 匹配规则。规定什么方法被拦截、需要处理什么方法
* 定义切入点
* @Pointcut("匹配规则")
*
* Aop 切入点表达式简介
* 1. 执行任意公共方法:
* execution(public *(..))
* 2. 执行任意的set方法
* execution(* set*(..))
* 3. 执行com.xxxx.service包下任意类的任意方法
* execution(* com.xxxx.service.*.*(..))
* 4. 执行com.xxxx.service 包 以及子包下任意类的任意方法
* execution(* com.xxxx.service..*.*(..))
*
* 注:表达式中的第一个* 代表的是方法的修饰范围
* 可选值:private、protected、public (* 表示所有范围)
*/
@Pointcut("execution (* com.xxxx.service..*.*(..) )")
public void cut(){}
/**
* 声明前置通知 并将通知应用到定义的切入点上
* 目标类方法执行前 执行该通知
*
*/
@Before(value = "cut()")
public void before() {
System.out.println("前置通知.....");
}
/**
* 声明返回通知 并将通知应用到定义的切入点上
* 目标类方法(无异常)执行后 执行该通知
*
*/
@AfterReturning(value = "cut()")
public void afterReturn() {
System.out.println("返回通知.....");
}
/**
* 声明最终通知 并将通知应用到定义的切入点上
* 目标类方法(无异常或有异常)执行后 执行该通知
*
*/
@After(value = "cut()")
public void after() {
System.out.println("最终通知.....");
}
/**
* 声明异常通知 并将通知应用到定义的切入点上
* 目标类方法出现异常时 执行该通知
*/
@AfterThrowing(value="cut()",throwing = "e")
public void afterThrow(Exception e) {
System.out.println("异常通知....." + " 异常原因:" + e.getCause());
}
/**
* 声明环绕通知 并将通知应用到切入点上
* 方法执行前后 通过环绕通知定义相应处理
* 需要通过显式调用对应的方法,否则无法访问指定方法 (pjp.proceed();)
* @param pjp
* @return
*/
@Around(value = "cut()")
public Object around(ProceedingJoinPoint pjp) {
System.out.println("前置通知...");
Object object = null;
try {
object = pjp.proceed();
System.out.println(pjp.getTarget() + "======" + pjp.getSignature());
// System.out.println("返回通知...");
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println("异常通知...");
}
System.out.println("最终通知...");
return object;
}
}
AOP总结
理解
1.面向切面,相比oop关注的是代码中的层或面
2.解耦,提高系统扩展性
3.提高代码复用
总结
1.连接点:每一个方法
2.切入点:匹配的方法集合
3.切面:连接点与切入点的集合决定了切面,横切关注点的抽象
4.通知:几种通知
5.目标对象:被代理对象
6.织入:程序运行期将切面应用到目标对象 并生成代理对象的过程
7.引入:在不修改原始代码的情况下,在程序运行期为程序动态引入方法或字段的过程
Spring是干什么的?
1.方便解耦,简化开发
2.方便的对程序进行拦截、运行、监控等功能
3.可以对事物声明
4.属于一个万能的框架,跟很多框架百搭
Spring怎么用
和SpringBoot的区别在于,需要在resource目录下创建xml,使用bean标签