千家信息网

SpringAOP的介绍和使用方法

发表于:2024-12-13 作者:千家信息网编辑
千家信息网最后更新 2024年12月13日,这篇文章主要介绍"SpringAOP的介绍和使用方法",在日常操作中,相信很多人在SpringAOP的介绍和使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Spr
千家信息网最后更新 2024年12月13日SpringAOP的介绍和使用方法

这篇文章主要介绍"SpringAOP的介绍和使用方法",在日常操作中,相信很多人在SpringAOP的介绍和使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"SpringAOP的介绍和使用方法"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、AOP介绍

AOP ,面向切面编程,在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。其实就是在代码运行,进行一定的包装,如在方法执行前、方法返回后、方法抛出异常后等地方进行一定的拦截处理或者叫增强处理

先讲一下AspectJ和Spring AOP关系,网上很多文章对AspectJ存在错误说法

AspectJ:

  • AspectJ 来自于 Eclipse 基金会,是Eclipse托管给Apache基金会的一个开源项目

  • 属于静态织入,它是通过修改代码来实现的,它的织入时机可以是:

    • Compile-time weaving:编译期织入

    • Post-compile weaving:也就是已经生成了 .class 文件,就要用到编译后织入

    • Load-time weaving:指的是在加载类的时候进行织入

  • AspectJ框架非常强大,它是 AOP 编程的完全解决方案。Spring AOP 致力于解决的是企业级开发中最普遍的 AOP 需求(方法织入)

  • AspectJ 在实际代码运行前完成了织入,所以大家会说它生成的类是没有额外运行时开销的

SpringAOP:

  • 基于动态代理来实现。默认地,如果使用接口的,用 JDK 提供的动态代理实现,如果没有接口,使用 CGLIB 实现

  • Spring AOP 和AspectJ并没有什么太多的关系,仅仅是Spring 延用了 AspectJ 中的概念,包括使用了 AspectJ 提供的 jar 包中的注解,但是不依赖于其实现功能

  • Spring AOP 需要依赖于 IOC 容器来管理,只能作用于 Spring 容器中的 Bean,它是使用纯粹的 Java 代码实现的,只能作用于 bean 的方法

  • Spring AOP 比 AspectJ 的性能稍差

二、Spring AOP术语解释

Joinpoint(连接点)
所谓连接点是指能够被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点(任何一个方法都可以称为连接点)

Pointcut(切入点)
切入点是指我们要对哪些Joinpoint进行拦截的定义(对哪个方法进行增强)

Advice(通知/增强)
通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)(要给它增加什么功能)

Target(目标对象)
代理的目标对象

Weaving(织入)
是指把增强应用到目标对象来创建新的代理对象的过程(怎样得到代理对象)

Proxy(代理)
一个类被AOP织入增强后,就产生一个结果代理类

Aspect(切面)
是切入点和通知的结合,构成切面,我们可以使用注解或者xml进行配置

三、Spring AOP注解使用

1. 在 xml 中配置
开启 @AspectJ 的注解,还有其它方式,这里不介绍

2. 使用@Aspect注解
定义实现AOP的配置类
@Aspect 注解要作用在 bean 上面

@Component@Aspectpublic class LogAspect {}

3. 配置 Pointcut
用于定义哪些方法需要被增强或者说需要被拦截

    @Pointcut(""execution(* com.ljj.service(..))"")private void controllerAspect() {// TODO Auto-generated method stub}     @Pointcut("@annotation(com.ljj.annotation.Log)")private void controllerAspect1() {// TODO Auto-generated method stub}@Pointcut(""within(com.ljj.service..*)"")private void controllerAspect2() {// TODO Auto-generated method stub}@Pointcut("bean(*Service)")private void controllerAspect3() {// TODO Auto-generated method stub}
  • execution ,正则匹配方法签名

  • @annotation。匹配对应注解的方法

  • within,指定所在类或所在包下面的方法

  • bean(idOrNameOfBean), 匹配 bean 的名字

4. 配置 Advice

   @Aspectpublic class AdviceExample {// 下面方法就是写拦截 "dao层实现"@Before("com.ljj.aop.dataAccessOperation()")public void doAccessCheck() {// ... 实现代码}@Before("execution(* com.ljj.dao.*.*(..))")public void doAccessCheck() {// ... 实现代码}@AfterReturning("com.ljj.aop.dataAccessOperation()")public void doAccessCheck() {// ...}@AfterReturning(pointcut="com.ljj.aop.dataAccessOperation()",returning="retVal")public void doAccessCheck(Object retVal) {// 这样,进来这个方法的处理时候,retVal 就是相应方法的返回值,是不是非常方便// ... 实现代码}// 异常返回@AfterThrowing("com.ljj.aop.dataAccessOperation()")public void doRecoveryActions() {// ... 实现代码}@AfterThrowing(pointcut="com.ljj.aop.dataAccessOperation()",throwing="ex")public void doRecoveryActions(DataAccessException ex) {// ... 实现代码}// 注意理解它和 @AfterReturning 之间的区别,这里会拦截正常返回和异常的情况@After("com.ljj.aop.dataAccessOperation()")public void doReleaseLock() {// 通常就像 finally 块一样使用,用来释放资源。// 无论正常返回还是异常退出,都会被拦截到}// 既能做 @Before 的事情,也可以做 @AfterReturning 的事情@Around("com.ljj.businessService()")public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {// start stopwatchObject retVal = pjp.proceed();// stop stopwatchreturn retVal;}}

上面Advice都已经匹配了对应的PointCut,这样定义可以不用再定义PointCut了。也可以使用下面这种PointCut + Advice

//定义日志注解@Target({ ElementType.PARAMETER, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Log {//操作名String optName();//操作类型OperateType optType();//操作表名String optTable();//操作编码String optCode();  }   @Pointcut("@annotation(com.ljj.annotation.Log)")private void controllerAspect() {// TODO Auto-generated method stub}//日志切面@Around("controllerAspect()")public Object around(ProceedingJoinPoint pjp) throws Throwable {   try {               //方法执行前操作result = point.proceed();//方法执行后操作} catch (Exception e) {e.printStackTrace();}}

到此,关于"SpringAOP的介绍和使用方法"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0