Spring学习笔记03:AOP(Aspect Oriented Programming),面向切面编程

一、什么是AOP?

这是一种编程思想,而不是某种特定的技术。它的作用主要是将重复的代码抽取出来,然后再织入到程序中。最好理解的例子就是Javaweb中的过滤器filter,就是有这种面向切面编程的思想。

二、AOP是基于什么实现的呢?

aop基于动态代理(spring优先选择JDK的Proxy代理,但是spring不要我们去实现动态代理,我们只需要进行一定的配置即可)
Proxy: 被代理的对象必须实现接口
Cglib: 被代理的对象不能被final修饰,基于继承

三、AOP的专用的术语

切入点:最终增强的方法

通知/增强:代理中增强的代码

切面:通知+切入点,通知应用到哪个切入点

目标:被代理对象

织入:将切面的代码应用到目标对象的过程

代理:增强被代理对象生成一个增强的代理对象

四、AOP有五种通知类型:

前置通知before,在方法前执行通知

最终通知after,无论方法是否执行成功,该通知都会执行,有点finally的感觉

成功通知afterReturning ,方法执行成功才执行

异常通知afterThrowing,方法执行出现异常执行

环绕通知around,可以自定义通知执行位置

五、举个例子理解上面的名词:

1.先导包:
 
  
		org.aspectj
		aspectjweaver
		1.8.10


	org.aspectj
	aspectjrt
	1.8.10

  
  
	org.springframework
	spring-context
	5.0.8.RELEASE



	org.springframework
	spring-test
	5.0.8.RELEASE
	test



     junit
     junit
     4.12
     test
 

2.创建通知对象的目标对象

AccountService接口

public interface AccountService {
	public void save()
}

AccountServiceImpl 实现AccountService接口

public class AccountServiceImpl implements AccountService {

	@Override
	public void save() {
		System.out.println("save操作");
		//int a = 1/0;
	
}

3.创建通知对象

public class MyAdvice {
	//前置通知,在目标方法执行前先执行
	public void before() {
		System.out.println("前置通知");
	}
	//最终通知,无论目标方法是否成功执行,最终都会执行该通知
	public void after() {
		System.out.println("后置通知");
	}
	//成功通知,目标方法成功执行后才执行该通知
	public void afterReturning() {
		System.out.println("成功通知");
	}
	//异常通知,目标方法执行出现异常才执行该通知
	public void afterThrowing() {
		System.out.println("异常通知");
	}
	//环绕通知,手动调用目标方法,可以设置通知的位置
	public void around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("环绕通知前");
		pjp.proceed();//调用目标方法
		System.out.println("环绕通知后");
	}
}

注意,环绕通知红框中是固定用法
Spring学习笔记03:AOP(Aspect Oriented Programming),面向切面编程_第1张图片

4.aop配置文件



	
	
	
	
	
		
	
		
		
		
		
			
			
			
			
			
		
	
	
	

*通配符,该通配符主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词
…通配符,该通配符表示0个或多个项
切点表达式:public * com.spring_demo.ioc.service.*ServiceImpl.*(..)
表达式表示在包com.spring_demo.ioc.service下以ServiceImpl结尾的类的所有公共方法,无论返回值是什么?方法名是什么?方法参数是什么?都是切点
第一个"*“表示无论方法是什么返回值类型都是切点,你可以自定义未void/int等等(则表示只有返回值类型跟你配置一样时才是切点)
第二个”*“表示以ServiceImpl结尾的类
第三个”*"表示无论方法名是什么
最后(..)表示无法方法参数是什么
切点

5.进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-aop.xml")
public class TestAOP {
	@Resource(name="accountService")
	AccountService accountService;
	@Test
	public void test1() {
		accountService.save();
	}
}

下面是加载class中的配置文件applicationContext-aop.xml
在这里插入图片描述
测试结果:
Spring学习笔记03:AOP(Aspect Oriented Programming),面向切面编程_第2张图片
修改AccountServiceImpl的代码,增加异常代码int a=1/0;

public class AccountServiceImpl implements AccountService {

	@Override
	public void save() {
		System.out.println("save操作");
		int a = 1/0;
}

再次测试,发现异常通知执行,成功通知没有执行:
Spring学习笔记03:AOP(Aspect Oriented Programming),面向切面编程_第3张图片

最后总结:

切入点:上面测试中的切入点就是AccountServiceImpl中的save方法

通知/增强:通知对象MyAdvice中的五种通知

切面:通知+切入点

目标:被代理对象指AccountServiceImpl

织入:将切面的代码应用到目标对象的过程

代理:下面注入的是AccountServiceImpl的增强对象在这里插入图片描述

你可能感兴趣的:(spring)