-
什么是AOP?
AOP是面向切面编程,采用横向抽取机制,取代传统纵向继承机制,将业务无关的代码解耦,适用于性能监视,操作日志的记录,权限校验等。横向抽取即通过代理向目标方法织入增强方法。 -
Spring AOP
Spring中Aop底层基于动态代理实现的。
目标对象如果有接口,自动使用jdk动态代理。
如果没有接口,自动使用cglib动态代理。
(底层自动切换,不需要人为手动修改) -
什么是目标对象?
(Target)目标对象:要被增强(处理)的方法的对象。企业开发中,一般是以业务层的对象作为目标对象 -
怎么找到目标对象需要增强(处理)的方法?
Joinpoint(连接点)和PointCut(切入点)
joinpoint:指代需要增强(处理)的目标对象的特定方法(要处理的方法)
PointCut:切入点就是表达式(包名.类名.方法名),用来找到对应的要增强(处理)的目标对象的特定方法(怎么找连接点) -
如何对需要增强(处理)的方法进行处理?
Aspect(切面类)与Advice(通知)
Aspect(切面类):Advice所在的类,称为切面类
是切入点和通知的结合
Advice(通知):增强目标对象特定方法的方法,根据触发位置不同,而分成
前置通知Before(目标对象特定方法执行之前触发),@Before("pointcut()") public void before(JoinPoint jp){ //获得要处理目标对象的方法名以及方法的参数 System.out.println("前置通知:在目标对象方法执行之前执行:"); System.out.println("拦截到要处理的方法的名字"); String name = jp.getSignature().getName();//要处理目标对象的方法的方法名 System.out.println("方法名:"+name); System.out.println("获得目标对象的方法的参数:"); Object[] args = jp.getArgs(); for (Object arg : args){ System.out.println("参数:"+arg); } }
后置通知AfterReturning(目标对象特定方法执行结束以后触发,且没有出现异常),//后置通知:目标对象方法执行结束以后,执行后置通知(可以获得当前方法的返回值) @AfterReturning(value = "pointcut()",returning = "result") public void afterReturning(Object result){ System.out.println("后置通知:获得目标对象方法的返回值"); System.out.println(result); }
最终通知After,//最终通知:最后被执行 @After("pointcut()") public void myAfter(){ System.out.println("最终被执行!"); }
异常通知AfterThrowing(目标对象特定方法出现异常触发),
异常用的是Exception的父类,Throwable//异常通知:只有当目标对象,出现异常,才执行异常通知。反之如果没有异常,不执行通知。 @AfterThrowing(value = "pointcut()",throwing = "ex") public void exception(JoinPoint joinPoint,Throwable ex){ System.out.println(joinPoint.getSignature()+"方法抛出异常了"); System.out.println(ex.getMessage()); }
环绕通知Around(目标对象特定方法执行前后分别被触发)
频繁的出现execution(* com.kkb.spring.service.*.*(..))要进行封装//环绕通知:在目标对象方法执行前后分别执行(调用目标对象方法的时候,执行环绕通知) @Around("pointcut()") public Object around(ProceedingJoinPoint proceedingJoinPoint)throws java.lang.Throwable{ System.out.println("环绕通知----------------------目标对象方法执行之前"); //执行目标对象的方法 Object result = proceedingJoinPoint.proceed(); System.out.println("环绕通知----------------------目标对象方法执行之后"); return result; }
通过配置文件进行控制@Pointcut("execution(* com.kkb.spring.service.*.*(..))") private void pointcut(){}
public void before(JoinPoint jp){ //获得要处理目标对象的方法名以及方法的参数 System.out.println("前置通知:在目标对象方法执行之前执行:"); } public void afterReturning(Object result){ System.out.println("后置通知:获得目标对象方法的返回值"); System.out.println(result); } public void exception(JoinPoint joinPoint,Throwable ex){ System.out.println(joinPoint.getSignature()+"方法抛出异常了"); System.out.println(ex.getMessage()); } public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{ System.out.println("环绕通知----------------------目标对象方法执行之前"); //执行目标对象的方法 Object result = proceedingJoinPoint.proceed(); System.out.println("环绕通知----------------------目标对象方法执行之后"); return result; } public void myAfter(){ System.out.println("最终被执行!"); }
<context:component-scan base-package="com.kkb.spring.service com.kkb.spring.aop"></context:component-scan> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> <aop:config> <!--切入点:可以考虑给目标对象中任意的一个方法添加一个切入点--> <aop:pointcut id="t1" expression="execution(* com.kkb.spring.service.*.insert*(..))"/> <aop:pointcut id="t2" expression="execution(* com.kkb.spring.service.*.update*(..))"/> <aop:pointcut id="t3" expression="execution(* com.kkb.spring.service.*.delete*(..))"/> <aop:pointcut id="t4" expression="execution(* com.kkb.spring.service.*.find*(..))"/> <!--切面:切入点和通知结合--> <aop:aspect ref="myAspect2"> <aop:before method="before" pointcut-ref="t1"/> <aop:before method="before" pointcut-ref="t4"/> <aop:after-returning method="afterReturning" pointcut-ref="t4" returning="result"/> <aop:after-throwing method="exception" pointcut-ref="t4" throwing="ex"></aop:after-throwing> <aop:around method="around" pointcut-ref="t1"/> <aop:after method="myAfter" pointcut-ref="t1"/> </aop:aspect> </aop:config>
- *:0-多个字符
.. :在方法的形参列表中,表示参数任意。在包名后,表示当前包及其子包
pointcut表达式格式:
execution(访问权限 返回值类型 包名.类名.方法名(参数列表) 异常类型)
execution(* com.jwt.aop.*.*(..))表示aop包下任意类中的任意方法
execution(* com.jwt..*.*(..))表示jwt包及其子包下任意类中的任意方法
Spring(2)AOP
最新推荐文章于 2023-11-27 20:23:52 发布