Java Spring AOP
Spring AOP(面向切面,Asoect-Oriented Programming) Spring AOP(面向切面,Asoect-Oriented Programming)即面向切面变成,依赖并与OO(面向对象,Object Oriented)即面向对象编程相辅相成,这主要体现在当面向切面过程时,先对业务逻辑进行抽象,而这个业务逻辑抽象是由面向对象(OO,Object Oriented)。在面向切面编程之中,最基本的单元是切面(Aspect):
Asoect-Oriented Programming 面向切面术语
ID
DA
FA
切面 (Aspect)
至封装横切到系统功能(事物处理)的类;
1
连接点 (Joinpoint)
指程序运行中的一些时间点,如方法的异常或抛出
2
切入点 (Pointcut)
指需要处理的连接点
3
通知 (增强处理)
由切面添加到特定的连接点(满足切入点规则)的一段代码
4
引入 (Introduction)
允许在现有的实现类中添加自定义的方法以及属性
5
目标对象 (Target Object)
指所有被通知的对象
6
代理 (Proxy)
通知应用到目标对象之后,被动态创建的对象
7
织入 (Weaving)
将切面代码插入到目标对象上,从而生成代理对象的不同
8
通俗点的来讲就是:
ID
DA
FA
切面
就是将所有共有或集成的功能实现,如我们可以将一块一块的组建合并为一个切面
1
通知
也就是且面的具体实现,以指定的切入点作为规则来寻找或添加的一段代码
2
连接点
也就是说程序运行中能够插入切面的连接地点
3
切入点
即用于定义通知应该切入到那些的链接点上(不同的通知用于需要切入不同的连接点上)
4
目标对象
也就是书所有被通知的对象,都是目标对象
5
代理对象
当通知到目标对象之后,就会被变成一个动态的对象 代理对象的功能等于目标对象的核心业务逻辑功能+共有对象功能 是程序运行中的产物
6
织入
将切面代码插入到目标的对象上,生成代理对象的不同
7
切面(Aspect) 通过上图可以看出,通过切面Aspect分别在,在业务类1和业务2中可以看出,分别加入了日志记录、性能统计、安全控制、事物处理等操作。也就是说在一个类中,加入了日志记录、性能统计、安全控制、事物处理等功能或构造方法。
切入点(Pointcut) 切入点(Pointcut)是指需要处理的连接点,在Spring AOP面向切面编程中,所有的方法执行都是连接点,而切入点是一个描述信息,修饰的是链接点,可通过切入点来链接需要被处理,而切面、连接点、切入点的关系如下; 而连接点即程序运行中的调用或异常抛出,但切入点主要处理需要处理的连接点(在Spring 面向切面中,所有方法都是连接点),而切面指的就是事物处理的类。
AspectJ 基于注解开发 AspectJ是一个面向切面AOP的一个框架,扩展了Java语言和定义了AOP语法,基于注解的开发AsoectJ会比和XML配置开发Aspect便捷许多没而Spring中通知的目标方法的连接点位置主要可以分为以下六种类型:
ID
DA
FA
环绕通知
在目标方法执行前和执行后的实施增强
1
前置通知
在目标方法执行前实施的增强
2
后置返回通知
在目标方法成够执行后实施增强
3
最终通知即后置通知
目标方法执行后进行增强,与后置返回通知不同的不管发生异常,都要执行该通知
4
异常通知
在方法抛出异常后实施增加
5
引入通知
在目标类中添加一些新的方法和属性,用于修改目标类
6
AspectJ 注解
ID
DA
FA
@Aspect
声明一个切面
1
@Pointcut
用于定义切入点,使用需要定义一个切入点的Viod方法,且方法体为空的普通方法
2
@Before
定义前置通知,通常为其指定value属性值
3
@AfterReturning
定义后置返回通知,使用时为其指定value属性值
4
@Around
用于定义一个环绕通知,在使用是也通常为其制定为value属性值 5
@AfterThrowing
定义一个异常通知,使用是通常为其指定value属性值
6
@After
用于定义后置即最终通知,使用时通常使用value属性值
7
前提条件 在开发项目之前,需要使用六个Spring核心的依赖包,分别为aop、aspects、beans、context、core、expression ,之后还需要commons-logging,下载地址为:“https://downloads.apache.org//commons/logging/binaries/commons-logging-1.2-bin.zip” ,然后还需要一个外部第三方依赖包为aspectjweaver.jar,下载地址为:“https://repo1.maven.org/maven2/org/aspectj/aspectjweaver/1.9.2/aspectjweaver-1.9.2.jar”
创建实现类的接口 aspectj.dao TestDao.java 1 2 3 4 5 6 7 package aspectj.dao;public interface TestDao { public void save () ; public void modify () ; public void delete () ; }
TestDaoImpl.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package aspectj.dao;import org.springframework.stereotype.Repository;@Repository("testDao") public class TestDaoImpl implements TestDao { @Override public void save () { System.out.println("save - TestDaoImpl" ); } @Override public void modify () { System.out.println("modify - TestDaoImpl" ); } @Override public void delete () { System.out.println("delete - TestDaoImpl" ); } }
创建切面类 aspectj.annotaition MyAspect.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 package aspectj.annotaition;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component;@Aspect @Component public class MyAspect { @Pointcut("execution(* aspectj.dao.*.*(..))") private void myPointCut () { } @Before("myPointCut()") public void before (JoinPoint joinpoint) { System.out.println("前置通知" ); System.out.println("目标类对象:" + joinpoint.getTarget() + "被增强处理的方法:" + joinpoint.getSignature().getName()); } @AfterReturning("myPointCut()") public void afterReturing (JoinPoint joinpoint) { System.out.println("后置返回通知:" + "模拟删除临时文件" ); System.out.println("被增强处理的方法" + joinpoint.getSignature().getName()); } @Around("myPointCut()") public Object around (ProceedingJoinPoint procedingjoinpoint) throws Throwable { System.out.println("环绕开始,执行目标方法前模拟开启事物" ); Object object = procedingjoinpoint.proceed(); System.out.println("环绕结束,执行目标方法后模拟关闭事物" ); return object; } @AfterThrowing(value="myPointCut()",throwing="e") public void except (Throwable e) { System.out.println("异常通知" + "程序执行异常" + e.getMessage()); } @After("myPointCut()") public void after () { System.out.println("最终通知,模拟释放" ); } }
配置类 aspectj.config AOPTest.java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package aspecti.config;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import aspectj.dao.TestDao;public class AOPTest { public static void main (String args[]) { AnnotationConfigApplicationContext application = new AnnotationConfigApplicationContext (AspectjAOPConfig.class); TestDao testDaoAdvice = application.getBean(TestDao.class); testDaoAdvice.save(); System.out.println("-----------" ); testDaoAdvice.modify(); System.out.println("-----------" ); testDaoAdvice.delete(); application.close(); } }
AspectjAOPconfig.java 1 2 3 4 5 6 7 8 9 10 11 12 package aspecti.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration @ComponentScan("aspectj") @EnableAspectJAutoProxy public class AspectjAOPConfig {}
⬅️ Go back