Spring 核心技术之一 AOP

29 篇文章 1 订阅

什么是AOP

      AOP:(Aspect Oriented Programming),面向切面编程,是一个概念,并没有设定具体语言的实现

AOP的作用

      AOP哪些与业务无关,却为业务模块共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合行,并有利于未来的可操作行和可维护性。
#

AOP与OOP的区别

  • OOP引入封装,继承和多态等概念,建立一种对象层次结构,是针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分;OOP定义的是竖向的关系,即从上到下;
  • AOP是OOP(面向对象编程)的延续,是为分散的对象引入公共行为,是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异;AOP定义的是横向的关系,即从左到右

如何实现

实现AOP的技术,主要分为两大类:

  • 一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;
  • 二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

相关概念

这里写图片描述

  • Cross Cutting Concern 横切性关注点:

            是一种独立服务,它会遍布在系统的处理流程之中。我理解的是:横切性关注点是一个抽象的概念,日志处理通知,事物处理通知,安全处理通知等统称为横切性关注点,和通知的概念有点混淆,还有待理解。。。

  • Aspect 切面

            对横切性关注点的模块话。我理解的是:这说的模块化我理解的就是类,即将通知应用到哪些类上

  • Advice通知:

            对横切行关注点的具体实现。我理解的是:具体的实现,如在执行添加方法前,要执行日志操作,该日志具体的实现就称为通知

  • Pointcut 切入点:

            它定义类Advice应用到哪些JpinPoint上,对Spring来说是方法调用。我理解的是:一些相似操作的集合,比如说应用到所有的添加方法上,这些添加方法就可以理解为切入点

  • JoinPoint 连接点:

            Advice在应用程序上执行的点或时机,Spring只支持方法的JpinPoint。我理解的是:通知具体应用到的具体方法上,如应用到添加用户方法上,方法是具体的

  • Weave

            将Advice应用到Target Object上的过程叫织入,Spring支持的是动态织入。我理解的是:将通知应用到具体的连接点上,也即具体应用到哪个对象上

  • Target Object

            Advice被应用的对象。还有待理解。。。

  • Proxy

            Spring AOP默认使用JDK动态代理,它的代理是运行时创建,也可使用CGLIB代理。还有待理解。。。

  • Introduction

            动态得为类添加方法。还有待理解。。。


#
切入的5种方式
  1. Before —在所拦截方法执行前执行;
  2. After —在所拦截方法执行后执行;
  3. AfterReturning —在所拦截方法返回值后,执行;
  4. AfterThrowing —当所拦截方法抛出异常时,执行;
  5. Around —最为复杂的切入方式,可以包括上述4个方式,如错误处理为 AfterThrowing,权限管理为Before(最大区别就是:可以通过ProceedingJoinPoint获取参数或方法名,如getSignature())可获取修饰符+ 包名+组件名(类名) +方法名)

应用

      权限、错误处理、检查安全性、记录日志等

实现

过程:

  • 引入spring相关依赖包
  • 将横切行关注点模块化,即写为一个类
  • 指定Aspect,定义Advice和Pointcut

有两种实现方式:注解方式和配置文件方式

1.注解方式

      在配置文件中,启用Aspect对Annotation的支持

<aop:aspectj-autoproxy />

      Aspect模块:

//声明Aspect切面
@Aspect
public class SecurityHandler  {

	//定义切入点
	//该方法不是实际调用的,只是为了提供注解Pointcut,因为注解在类上,Pointcut的名称为addMethod()
	//此方法没有返回值和参数,该方法就是个标识,不进行调用
	//第一个*:返回值
	//第二个*:所有的add方法
	//...:方法参数
	@Pointcut("execution(* add*(..))")
	private void addAddMethod(){};
	
	//定义advice通知,before切入方式
	@Before("addAddMethod()")
	private void checkSecurity(){
		System.out.println("_______checkSecurity___________");
	}
}

      这样就实现了在所有的以add开头的方法执行前都会先执行,在此定义的checkSecurity()方法作为通知,即:

@Before("addAddMethod()")
private void checkSecurity(){
	System.out.println("_______checkSecurity___________");
}

      可以在Advice方法中加入JoinPoint参数,来获取客户端调用的方法名和方法的参数

2.配置文件方式:

	<bean id="securityHandler" class="com.bjpowernode.spring.SecurityHandler"></bean>

	<aop:config>
		<!-- 定义切面 -->
		<aop:aspect id="securityAspect" ref="securityHandler">
			<!-- 定义切入点 -->
			<!-- 所有以add开头的方法 -->
			<!-- <aop:pointcut id ="addMethod" expression="execution(* add*(..))"/> -->
			<!-- 该包下的所有方法 -->
			<!-- <aop:pointcut id ="addMethod" expression="execution(* com.bjpowernode.spring.*.*(..))"/> -->
			<!-- 该包下所有类的add开后或del开头的方法 -->
			<aop:pointcut id ="addMethod" expression="execution(* com.bjpowernode.spring.*.add*(..)) || execution(* com.bjpowernode.spring.*.del*(..))"/>

			<!-- 定义通知 -->
			<aop:before method="checkSecurity" pointcut-ref="addMethod"/>
		</aop:aspect>
	</aop:config>

总结spring对AOP的支持:

  1. 如果目标对象实现了接口,在默认情况下会采用JDK动态代理实现AOP,也可强制使用CGLIB生成代理实现AOP
  2. 如果目标对象没有实现接口,就必须引入CGLIB,spring会在JKD的动态代理和CGLIB代理之间切换

JDK动态代理和CGLIB代理的区别:

  1. JDK动态代理实现了接口的类进行代理
  2. CGLIB代理可实现对类的代理,主要对指定的类生成一个子类

如何强制使用CGLIB代理:

  1. 加入CGLIB库
  2. 在配置文件中声明强制使用CGLIB代理(默认是使用的JDK代理)
<aop:aspectj-autoproxy proxy-target-class="true" />

总结

      AOP就是给多个不相关的同等级(所以是横切性)的类提供共同的服务,而这些服务与具体的类的业务逻辑是不相关的,这样减少了代码的书写,降低程序耦合

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值