博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring系列教程六:AOP详细讲解
阅读量:7038 次
发布时间:2019-06-28

本文共 8046 字,大约阅读时间需要 26 分钟。

hot3.png

AOP 概述

什么是 AOP

AOP:全称是 Aspect Oriented Programming 即:面向切面编程。

189ba989b187db7315970078747a1216d6b.jpg

AOP技术是对OOP技术的一种延伸,AOP是面向纵向,OOP是面向横向。简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的

基础上,对我们的已有方法进行增强。

AOP 的作用以及优势

作用:在程序运行期间,不修改源码对已有方法前面和后面进行增强。

优势:减少重复代码、提高开发效率、维护方便

AOP实现方式

使用动态代理技术

基于xml方式的aop配置

实现步骤如下

fb48f5b34033b8fa3d4b459c199e4ac2c44.jpg

导入spring-aop jar包

org.springframework
spring-test
5.0.2.RELEASE
org.springframework
spring-context
4.3.6.RELEASE
commons-dbutils
commons-dbutils
1.6
mysql
mysql-connector-java
5.1.6
c3p0
c3p0
0.9.1.2
junit
junit
4.12
下面几个是必须要导的包
org.aspectj
aspectjweaver
1.9.2
aopalliance
aopalliance
1.0
log4j
log4j
1.2.12

需要增强方法的StudentDao类,和写增强方法的Userlogger类

package com.ithema.jdbc.dao;public class StudentDao {    //在执行add方法之前执行日志    public int add(int a,int b){        System.out.println("执行了add方法");        return a+b;    }    public  int jian(int a,int b){        System.out.println("执行了减法");        return a-b;    }   /* public void testexe(){        int i=10/0;    }*/}
package com.ithema.jdbc.aop;import org.apache.log4j.Logger;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import java.util.Arrays;/** * 切面: * 前置增强、后置增强、异常增强、最终增强、环绕增强 * * Spring aop完全是用动态代理实现的 * 但是动态代理又有两种,jdkk代理,cglib代理(更强大一些) * spirng aop:默认使用jdk代理,但是你的目标类没接口,会自动切换到cglib代理 */public class UserLogger {    //在目标方法调用之前执行该方法    Logger logger=Logger.getLogger(UserLogger.class);    public void before(JoinPoint jp){        logger.info("前置增强,目标类名"+jp.getTarget()+"里面的"+jp.getSignature().getName()+                "参数为:"+ Arrays.toString(jp.getArgs()));    }    //在目标方法调用之后执行该方法    //当方法抛出异常就不会执行了,所有该方法不适合做日志收集,因为发生了异常不执行该方法无法将日志保存下来    //所有后置增强用的很少    public void after(JoinPoint jp,Object result){        logger.info("后置增强,执行完类"+jp.getTarget()+"里面的"+jp.getSignature().getName()+                "方法,结果为:"+ result);    }    //在方法抛出异常后就会增强、没有异常就不会执行、如果用户try-catch,也不会增强    //执行错误的话,非常适合该增强(异常增强)    //Java异常体系,根类是Throwable    public void afterThorwing(JoinPoint jp,Throwable e){        logger.info("异常增强,执行类"+jp.getTarget()+"里面的"+jp.getSignature().getName()+                "方法抛出异常:"+e.getMessage());    }    //最终增强:无论是否有异常,都会执行,类似与finally,可以或者是认为是后置增强的升级版    public void finalafter(JoinPoint jp){        logger.info("最终增强:执行完类"+jp.getTarget()+"里面的"+jp.getSignature().getName());    }    //环绕增强,集合了前置添加后置,并且更加强大、当执行方法发生异常后面的就不执行了    //1、可以修改方法的参数 2、也可以修改方法的返回值( return result)    public Object around(ProceedingJoinPoint jp)throws Throwable{        Object [] args=jp.getArgs();//获取方法参数        //可以修改方法的参数        //args = new Object[]{20,1};        logger.info("环绕增强:方法为:"+jp.getArgs());        Object result=jp.proceed();//执行目标方法        //也可以修改方法的返回值        //return 100;        return result;    }}

配置aop约束到配置文件中,并实现ioc配置

使用 aop:aspect 配置切面,使用 aop:pointcut  配置切入点表达式

7c9d49daf07705566af1097d84ec717d40c.jpg

基于注解方式的aop配置

导入spring-aop jar包

org.springframework
spring-test
5.0.2.RELEASE
org.springframework
spring-context
4.3.6.RELEASE
commons-dbutils
commons-dbutils
1.6
mysql
mysql-connector-java
5.1.6
c3p0
c3p0
0.9.1.2
junit
junit
4.12
下面几个是必须要导的包
org.aspectj
aspectjweaver
1.9.2
aopalliance
aopalliance
1.0
log4j
log4j
1.2.12

配置aop约束到配置文件中,在配置文件中指定 spring 要扫描的包,开启 spring 对注解 AOP 的支持

使用注解配置增强方法

package com.bdqn.aop;import org.apache.log4j.Logger;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;import java.util.Arrays;@Component@Aspectpublic class UserLogger {    //在目标方法调用之前执行该方法    Logger logger=Logger.getLogger(UserLogger.class);    //定义切点    @Pointcut("execution(* com.bdqn.aop..*.*(..))")    public void pointcut(){}    @Before("pointcut()")    public void before(JoinPoint jp){        logger.info("前置增强,目标类名"+jp.getTarget()+"里面的"+jp.getSignature().getName()+                "参数为:"+ Arrays.toString(jp.getArgs()));    }    //在目标方法调用之后执行该方法    //当方法抛出异常就不会执行了,所有该方法不适合做日志收集,因为发生了异常不执行该方法无法将日志保存下来    //所有后置增强用的很少    public void after(JoinPoint jp,Object result){        logger.info("后置增强,执行完类"+jp.getTarget()+"里面的"+jp.getSignature().getName()+                "方法,结果为:"+ result);    }    //在方法抛出异常后就会增强、没有异常就不会执行、如果用户try-catch,也不会增强    //执行错误的话,非常适合该增强(异常增强)    //Java异常体系,根类是Throwable    @AfterThrowing(pointcut = "execution(* com.bdqn.aop..*.*(..))",throwing = "e")    public void afterThorwing(JoinPoint jp,Throwable e){        logger.info("异常增强,执行类"+jp.getTarget()+"里面的"+jp.getSignature().getName()+                "方法抛出异常:"+e.getMessage());    }    //最终增强:无论是否有异常,都会执行,类似与finally,可以或者是认为是后置增强的升级版    @After("execution(* com.bdqn.aop..*.*(..))")    public void finalafter(JoinPoint jp){        logger.info("最终增强:执行完类"+jp.getTarget()+"里面的"+jp.getSignature().getName());    }    //环绕增强,集合了前置添加后置,并且更加强大、当执行方法发生异常后面的就不执行了    //1、可以修改方法的参数 2、也可以修改方法的返回值( return result)    @Around("execution(* com.bdqn.aop..*.*(..))")    public Object around(ProceedingJoinPoint jp)throws Throwable{        Object [] args=jp.getArgs();//获取方法参数        //可以修改方法的参数        //args = new Object[]{20,1};        logger.info("环绕增强:方法为:"+jp.getArgs());        Object result=jp.proceed();//执行目标方法        //也可以修改方法的返回值        //return 100;        return result;    }}

使用spring整合junit4的方式写测试类

package com.bdqn.test;import com.bdqn.dao.StudentDao;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = "classpath:ApplicationContext.xml")public class Testaop {    @Autowired    private StudentDao studentDao;    @Test    public  void testaop(){        studentDao.add();        studentDao.jian(3,1);        System.out.println("执行了减法,结果为:");    }}

 

转载于:https://my.oschina.net/u/4115727/blog/3051472

你可能感兴趣的文章