SpringerAOP2

198 阅读3分钟

这是我参与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);
}

image.png

@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();
}

image.png

@After

最终通知语法

  • 属性 value 切入点表示式
  • 位置 在方法的上边 方法定义
  • 方法是public
  • 没有返回值,是void
  • 方法名自定义
  • 方法没有参数 特点
  • 在目标方法之后执行
  • 总会被执行
  • 可以做程序的收尾工作,关闭结果集,删除临时文件等等
  • 可以看多做Try -finally
@After("execution(* *..do*(..)))")
public void after(){
    System.out.println("最终通知执行");
}

我们执行刚才的两个例子

image.png

image.png

@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在执行期间,生成代理对象,通过代理对象执行业务方法,同时增强功能。