第三章 AOP面向切面编程

第三章 AOP 面向切面编程

3.1 动态代理
3.2 AOP 概述
3.3 AOP 编程术语
3.4 AOP 的实现

3.1 动态代理

可以在程序的执行过程中,创建代理对象。通过代理对象执行方法,给目标类增加额外的功能而不改变原来类中的代码(功能增强),在一定程度上减少代码重复。

1、JDK 动态代理:要求目标对象必须实现接口,通过 java.lang.reflect 包提供三个类支持代理模式 Proxy、Method 和 InvocationHandler 。

实现步骤:
1)创建目标类(如果目标类已经存在,此步骤可以省略)

	SomeService,SomeServiceImpl(目标类,实现 SomeService 接口)

2)创建 InvocationHandler 接口的实现类,在这个类实现给目标方法增加功能

public class MyInvocationHandler implements InvocationHandler {
	// 目标对象
	private Object target; 

	public MyInvocationHandler (Object target) {
		this.target = target;
	}
	
	// 通过代理对象执行方法时,会调用这个invoke()
	// 在这个方法里添加需要增加的功能
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object res = null;
		// 可以在目标方法前添加
		// xxxx 要增加的功能
		// 执行目标类的方法,通过 Method 类实现
		res = method.invoke(target,args);
		// 也可以在目标方法后添加
		// xxxx 要增加的功能
		return res;
	}
}

3)使用 jdk 中的类 Proxy 创建代理对象,实现创建对象的能力

// 创建目标对象
SomeService target = new SomeServiceImpl();

// 创建 InvocationHandler 对象
InvocationHandler handler = new MyInvocationHandler(target );

// 使用 Proxy 创建代理
SomeService proxy = (SomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);

// 通过代理执行方法,会调用 handler 中的 invoke()
// doSome() 是 SomeService 中的方法,在 SomeServiceImpl 中被实现
proxy.doSome();

2、CGLIB 动态代理:第三方工具库,创建代理对象。原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象,所以要求目标类必须能够被继承,即不能是 final 类。

3.2 AOP 概述

1、Aop是什么?

Aop 是基于动态代理,可以使用 jkd,cglib 两种代理方式。Aop 就是动态代理的规范化,把动态代理的实现步骤、方式都定义好了,让开发人员用一种统一的方式去使用动态代理。

2、怎么理解面向切面编程

AOP(Aspect Orient Programming)
Aspect :切面,给目标类增加的功能就是切面,比如日志、事务、统计信息、参数检查、权限限定都是切面。切面一般都是非业务方法,独立使用。
Orient :面向
Programming:编程

1)在分析项目功能时,需要找出切面
2)合理的安排切面的执行时间(在目标方法前还是目标方法后)
3)合理的安排切面的执行位置(在哪个类,在哪个方法)

3.3 AOP 编程术语

1)Aspect
2)JoinPoint:连接点,程序执行的某一个特定位置,如类初始前后,方法的运行前后,而 Spring 只支持方法的连接点
3)Pointcut:切入点,切点是匹配了一个或多个连接点。定义了切面在何处执行,切点的前提也是一个连接点,它是连接点的一个子集
4)Advice:通知,定义了切面是什么以及何时使用,Spring 中的通知有以下5种:

	前置通知(before):在目标方法执行之前执行的通知
	后置通知(after):在目标方法执行之后执行的通知,此时不关心方法是否成功执行
	返回通知(after-returning):在目标方法成功执行之后执行的通知
	异常通知(after-throwing):在目标方法抛出异常之后执行的通知
	环绕通知(around):通知包含了目标方法,可以在目标方法执行之前和执行之后执行自定义的行为。
以上五种分别对应 AspectJ 中的通知注解:@Before、@After、@AfterRunning、@AfterThrowing、@Around
	
5)Target:目标对象,给哪个类的方法增加功能,这个类就是目标对象

3.4 AOP 的实现

spring:spring 在内部实现了 aop 规范,能完成 aop 的工作,主要在事务处理时使用 aop,但我们在项目开发中很少使用 spring 框架中的 aop,因为其比较笨重。

aspectJ:是一个开源专门做 aop 的框架,spring 的框架中集成了 aspectJ 框架,有两种使用方式:
	1)xml 配置文件:配置全局事务
	2)注解:通常使用此种方式实现

使用 aspectJ 实现 aop 的基本步骤:

1)新建 maven 项目
2)添加 spring 和 aspectJ 依赖
3)创建目标类:接口和它的实现类
4)创建切面类:普通类
   在类的上面加入 @Aspect;在类中定义方法,方法就是切面要执行的功能代码;在方法上面加入 AspectJ 中的通知注解;指定切入点表达式 execution()
5)创建 spring 的配置文件:声明对象,把对象交给容器统一管理
	a、声明目标类对象
	b、声明切面类对象
	c、声明 aspect 框架中的自动代理生成器(用来完成代理对象的自动创建功能)标签,以下使用 Proxy 创建代理这步就可省略
6)从 spring 容器中获取目标对象(实际就是代理对象),通过代理执行方法,实现 aop 的功能增强
// spring 依赖
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.2.5.RELEASE</version>
</dependency>

// aspectj 依赖
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aspects</artifactId>
	<version>5.2.5.RELEASE</version>
</dependency>
/*
* @Aspect :是 Aspectj 框架中的注解
* 作用:表示当前类是切面类
* 切面类:用来给业务方法增加功能的类
* 位置:定义在类的上面
*/
@Aspect
public class MyAspect {
	/*
	* 定义方法,用来实现切面功能
	* 方法的定义要求:
	* 1、必须是公共方法(public)
	* 2、方法没有返回值(void)
	* 3、方法的名称自定义
	* 4、方法可以有参数也可以没有参数
	*/
	
	/* 
	* 此处以 @Before 注解为例 
	* 位置:定义在方法上面
	* 特点:
	* 1、在目标方法之前执行
	* 2、不会改变目标方法的执行结果
	* 3、不会影响目标方法的执行
	*/
	
	@Before(value="execution(public void 包名.类名.方法名(参数) 异常)")
	public void myBefore() {
	}
}
// 声明目标对象
<bean id="someService" class="xxx" />

// 声明切面对象
<bean id="myAspect" class="xxx" />

/* 声明自动代理生成器:使用 aspectj 框架内部的功能,创建目标对象的代理对象
* 创建代理对象是在内存中实现的,修改目标对象在内存中的结构,创建为代理对象,
* 所以目标对象就是被修改后的代理对象
*/
// aspectj-autoproxy 会把 spring 容器中的所有目标对象一次性都生成代理对象
<aop:aspectj-autoproxy />

// 以下这步可以省略
// 使用 Proxy 创建代理
SomeService proxy = (SomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),handler);

第二章 IoC控制反转

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值