这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战
Joint参数必须放在第一个位置。
@Around
- 属性:value 切入点表达式。
- 位置:在方法定义上边
- 返回值: onject表示目标方法希望得到的执行结果,(不一定是目标方法自己的返回值)
- ProceedingJoinPoint : 相当于反射中的method 用来执行方法等于method.invoke(),继承了JoinPoint() @Around的特点
- 在目标方法前后都能增强功能
- 控制目标方法是否执行,ProceedingJoinPoint.proceed()用来执行目标方法
- 修改目标方法的执行结果
public interface doService {
public String doAround(String name,Integer id);
}
@Override
public String doAround(String name, Integer id) {
System.out.println("执行了业务方法");
return name+id;
}
@Around("execution(* *..doAround(..)))")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行Around环绕通知打印日志时间"+new Date());
//Object proceed = pjp.proceed();
Object proceed = pjp.proceed();
// return "执行around,返回值是原方法返回值" +proceed;
return "执行around,返回值不是原方法返回值";
}
@Test
public void shouldAnswerWithTrue()
{
//配置文件地址
String configPath="ApplicationConttext.xml";
//2创建对象容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(configPath);
doService service= (doService) applicationContext.getBean("doSomeImpl");
Object obj =service.doAround("张三身高",188);
System.out.println(obj);
}
@AfterThorwing
语法
- 属性: value 切入点表达式
- throwing 自定义变量,表示目标方法抛出的异常,变量名必须和通知方法的形参一样
方法定义
- 方法是public
- 没有返回值,是void
- 方法名自定义
- 方法参数是Exception 特点
- 在目标方法抛出异常后执行,没有异常不执行
- 能获取到目标方法的异常信息
- 不是异常处理程序,而是得到发生异常的通知,可以用来监控目标方法发横异常然后通知
public String doThrowing();
@Override
public String doThrowing() {
return "执行业务方法"+ (1/0);
}
@AfterThrowing(value = "execution(* *..doThrowing(..)))",throwing = "ex")
public void afterThrowingAdvice(Exception ex) throws Throwable {
System.out.println("异常通知,目标方法执行异常时执行,异常原因"+ ex.getMessage());
}
@Test
public void shouldAnswerWithTrue()
{
//配置文件地址
String configPath="ApplicationConttext.xml";
//2创建对象容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(configPath);
doService service= (doService) applicationContext.getBean("doSomeImpl");
service.doThrowing();
}
@After
最终通知语法
- 属性 value 切入点表示式
- 位置 在方法的上边 方法定义
- 方法是public
- 没有返回值,是void
- 方法名自定义
- 方法没有参数 特点
- 在目标方法之后执行
- 总会被执行
- 可以做程序的收尾工作,关闭结果集,删除临时文件等等
- 可以看多做Try -finally
@After("execution(* *..do*(..)))")
public void after(){
System.out.println("最终通知执行");
}
我们执行刚才的两个例子
@PointCut
定义和管理切入点,不是通知注解
- 属性 value 切入点表达式
- 位置 再一个自定义的方法上边,看做切入点表达式的别名,别的窃取点表达式可以使用这个别名,就表达使用这个切入点
@Around("myCut()")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("执行Around环绕通知打印日志时间"+new Date());
//Object proceed = pjp.proceed();
Object proceed = pjp.proceed();
// return "执行around,返回值是原方法返回值" +proceed;
return "执行around,返回值不是原方法返回值";
}
@AfterThrowing(value = "myCut()",throwing = "ex")
public void afterThrowingAdvice(Exception ex) throws Throwable {
System.out.println("异常通知,目标方法执行异常时执行,异常原因"+ ex.getMessage());
}
@After("myCut()")
public void after(){
System.out.println("最终通知执行");
}
@Pointcut("execution(* *..do*(..)))")
public void myCut(){
}
AOP总结
AOP是一种动态的技术思想,目的是实现业务功能和非业务功能的解耦,当我们需要一些非业务的功能时,可以再不修改业务代码的强狂下,利用AOP在执行期间,生成代理对象,通过代理对象执行业务方法,同时增强功能。