spring-环绕通知 @Around

古城微笑少年丶 2022-11-26 00:48 389阅读 0赞

环绕通知

目标方法的前和后都能增加功能

在目标方法执行之前之后执行。被注解为环绕增强的方法要有返回值Object 类型。并
且方法可以包含一个ProceedingJoinPoint 类型的参数。接口ProceedingJoinPoint 其有-一个
proceed()方法,用于执行目标方法若目标方法有返回值,则该方法的返回值就是目标方法
的返回值
。最后,环绕增强方法将其返回值返回。该增强方法实际是拦截了目标方法的执行。

环绕通知的方法定义
  1. public公共
  2. 必须有一个返回值,推荐使用Object
  3. 方法名称自定义
  4. 方法参数,固定的参数 ProceedingJoinPoint

使用:

属性:value 切入表达式
位置:在方法定义的上面 @Around
特点:

  1. 它是功能最强的通知
  2. 在目标方法的前和后都能增加功能
  3. 控制目标方法是否被调用执行 使用if判断来执行 object = pjd.proceed();
    等同于method.invoke();—>就是 Object result = Dofirst();
  4. 修改原来的目标方法的执行结果。影响最后的调用结果
    参数: ProceedingJoinPoint
    作用:执行目标方法的
    返回值: 就是目标方法执行结果,执行的结果可以被修改

接口:

  1. public interface Someservice {
  2. String Dofirst(String name,int age);
  3. }

接口实现类:

  1. @Component("someService")
  2. public class SomeserviceImpl implements Someservice {
  3. @Override
  4. public String Dofirst(String name, int age) {
  5. System.out.println("------业务逻辑方法执行-------");
  6. return name;
  7. }
  8. }

增强功能类:

  1. @Component("myAspect3")
  2. @Aspect
  3. public class MyaspectJ {
  4. @Around(value = "execution(* *..SomeserviceImpl.Dofirst(..))")
  5. public Object myAspectJ(ProceedingJoinPoint pjd) throws Throwable {
  6. Object object =null;
  7. //在目标方法之前的功能增加
  8. System.out.println("调用的时间:"+new Date());
  9. // 1. 目标方法的调用
  10. object = pjd.proceed();
  11. System.out.println("事务的调用");
  12. //修改目标方法的返回值
  13. object= object+"2020;
  14. return object;
  15. }
  16. }

配置文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  3. <context:component-scan base-package="cn.com.Ycy.spring_aspectJ.bao03"/>
  4. <aop:aspectj-autoproxy/>
  5. </beans>

测试类

  1. @Test
  2. public void test04(){
  3. String config="Applicationcontext2.xml";
  4. ApplicationContext ac = new ClassPathXmlApplicationContext(config);
  5. //从容器获取目标对象
  6. cn.com.Ycy.spring_aspectJ.bao03.Someservice someservice = (cn.com.Ycy.spring_aspectJ.bao03.Someservice) ac.getBean("someService");
  7. //通过代理对象执行方法,实现目标方法执行时,增强了功能
  8. System.out.println("someservice:"+someservice.getClass().getName());
  9. String str = someservice.Dofirst("ycy",24); //就相当于调用 myAspectJ这个方法
  10. System.out.println(str);
  11. //someService
  12. }

输出结果

  1. someservice:com.sun.proxy.$Proxy13
  2. 调用的时间:Mon Aug 03 17:56:13 CST 2020
  3. ------业务逻辑方法执行-------
  4. 事务的调用
  5. ycy-2020

不用接口也是可以的,直接就是对普通类进行功能增强

普通类

  1. @Component("someService1")
  2. public class someService {
  3. public String Dofirst(String name, int age) {
  4. System.out.println("------业务逻辑方法执行-------");
  5. return name;
  6. }
  7. }

功能增强类

  1. @Component("myAspect3")
  2. @Aspect
  3. public class MyaspectJ {
  4. @Around(value = "execution(* *..someService.Dofirst(..))")
  5. public Object myAspectJ(ProceedingJoinPoint pjd) throws Throwable {
  6. Object object =null;
  7. //在目标方法之前的功能增加
  8. System.out.println("调用的时间:"+new Date());
  9. // 1. 目标方法的调用
  10. object = pjd.proceed();
  11. System.out.println("事务的调用");
  12. object= object+"-18204229";
  13. return object;
  14. }
  15. }

总结

环绕通知:常用于做事务,事务开启,执行方法
使用接口的代理是 someservice:com.sun.proxy. P r o x y 13 ∗ ∗ j d k 动 态 代 理 ∗ ∗ ∗ ∗ 不 使 用 接 口 的 是 ∗ ∗ : s o m e s e r v i c e : c n . c o m . Y c y . s p r i n g a s p e c t J . b a o 04. s o m e S e r v i c e Proxy13 **jdk动态代理** **不使用接口的是**: someservice:cn.com.Ycy.spring_aspectJ.bao04.someService Proxy13∗∗jdk动态代理∗∗∗∗不使用接口的是∗∗:someservice:cn.com.Ycy.springa​spectJ.bao04.someService E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB$a489942e
是CGLIB代理
如果有接口,但是想使用CGLIB代理可以修改配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  3. <context:component-scan base-package="cn.com.Ycy.spring_aspectJ.bao05"/>
  4. <aop:aspectj-autoproxy proxy-target-class="true"/>
  5. </beans>

发表评论

表情:
评论列表 (有 0 条评论,389人围观)

还没有评论,来说两句吧...

相关阅读

    相关 spring-环绕通知 @Around 注解

    > 环绕通知:常用于做事务,事务开启,执行方法。在目标方法执行之前之后执行。 > 被注解为环绕增强的方法要有返回值,Object类型。并且方法可以包含一个Proceedin