spring-环绕通知 @Around
环绕通知
目标方法的前和后都能增加功能
在目标方法执行之前之后执行。被注解为环绕增强的方法要有返回值,Object 类型。并
且方法可以包含一个ProceedingJoinPoint 类型的参数。接口ProceedingJoinPoint 其有-一个
proceed()方法,用于执行目标方法。若目标方法有返回值,则该方法的返回值就是目标方法
的返回值。最后,环绕增强方法将其返回值返回。该增强方法实际是拦截了目标方法的执行。
环绕通知的方法定义
- public公共
- 必须有一个返回值,推荐使用Object
- 方法名称自定义
- 方法参数,固定的参数 ProceedingJoinPoint
使用:
属性:value 切入表达式
位置:在方法定义的上面 @Around
特点:
- 它是功能最强的通知
- 在目标方法的前和后都能增加功能
- 控制目标方法是否被调用执行 使用if判断来执行 object = pjd.proceed();
等同于method.invoke();—>就是 Object result = Dofirst(); - 修改原来的目标方法的执行结果。影响最后的调用结果
参数: ProceedingJoinPoint
作用:执行目标方法的
返回值: 就是目标方法执行结果,执行的结果可以被修改
接口:
public interface Someservice {
String Dofirst(String name,int age);
}
接口实现类:
@Component("someService")
public class SomeserviceImpl implements Someservice {
@Override
public String Dofirst(String name, int age) {
System.out.println("------业务逻辑方法执行-------");
return name;
}
}
增强功能类:
@Component("myAspect3")
@Aspect
public class MyaspectJ {
@Around(value = "execution(* *..SomeserviceImpl.Dofirst(..))")
public Object myAspectJ(ProceedingJoinPoint pjd) throws Throwable {
Object object =null;
//在目标方法之前的功能增加
System.out.println("调用的时间:"+new Date());
// 1. 目标方法的调用
object = pjd.proceed();
System.out.println("事务的调用");
//修改目标方法的返回值
object= object+"2020;
return object;
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<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">
<context:component-scan base-package="cn.com.Ycy.spring_aspectJ.bao03"/>
<aop:aspectj-autoproxy/>
</beans>
测试类
@Test
public void test04(){
String config="Applicationcontext2.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//从容器获取目标对象
cn.com.Ycy.spring_aspectJ.bao03.Someservice someservice = (cn.com.Ycy.spring_aspectJ.bao03.Someservice) ac.getBean("someService");
//通过代理对象执行方法,实现目标方法执行时,增强了功能
System.out.println("someservice:"+someservice.getClass().getName());
String str = someservice.Dofirst("ycy",24); //就相当于调用 myAspectJ这个方法
System.out.println(str);
//someService
}
输出结果
someservice:com.sun.proxy.$Proxy13
调用的时间:Mon Aug 03 17:56:13 CST 2020
------业务逻辑方法执行-------
事务的调用
ycy-2020
不用接口也是可以的,直接就是对普通类进行功能增强
普通类
@Component("someService1")
public class someService {
public String Dofirst(String name, int age) {
System.out.println("------业务逻辑方法执行-------");
return name;
}
}
功能增强类
@Component("myAspect3")
@Aspect
public class MyaspectJ {
@Around(value = "execution(* *..someService.Dofirst(..))")
public Object myAspectJ(ProceedingJoinPoint pjd) throws Throwable {
Object object =null;
//在目标方法之前的功能增加
System.out.println("调用的时间:"+new Date());
// 1. 目标方法的调用
object = pjd.proceed();
System.out.println("事务的调用");
object= object+"-18204229";
return object;
}
}
总结
环绕通知:常用于做事务,事务开启,执行方法
使用接口的代理是 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.springaspectJ.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代理可以修改配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<context:component-scan base-package="cn.com.Ycy.spring_aspectJ.bao05"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
还没有评论,来说两句吧...