@Around环绕通知增强方法有ProceedingJoinPoint参数

174 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情

最后,环绕增强方法将其返回值返回。该增强方法实际是拦截了目标方法的执行。

接口方法:

public interface SomeService {\
    String doSome(String name, int age);\
}

接口方法的实现:

@Component\
public class SomeServiceImpl implements SomeService {\
    @Override\
    public String doSome(String name, int age) {\
        System.*out*.println(name+"doSome方法被调用 (主业务方法)");\
        return "abcd";\
    }

}

定义切面:

@Aspect\
@Component\
public class MyAspect {\
     */****\
**** *环绕通知方法的规范**\
***** 1)* *访问权限是* *public**\
*** 2)* *切面方法有返回值* *,* *此返回值就是目标方法的返回值* *.**\
*** 3)* *切面方法的名称自定义**\
***** 4)* *切面方法有参数* *,* *参数就是目标方法* *.* *它是* *ProceedingJoinPoint* *的类型**\
***** 5)* *必须要回避异常* *Throwable**\
*** 6)* *使用* *@Around* *注解**\
***** 7)* *参数* *:value:* *指定切入点表达式**\
*******\
***/**\
*//    普通的环绕通知实现\
    @Around(value = "execution(* com.bjpowernode.s03.SomeServiceImpl.*(..))")\
    public Object myAround(ProceedingJoinPoint pjp)throws Throwable{\
        //前切功能增强\
        System.*out*.println("环绕通知中前切功能 .............");\
        //调用目标方法\
        Object obj = pjp.proceed();  //method.invoke();\
        //后切功能增强\
        System.*out*.println("环绕通知中后切功能 .............");\
        return obj.toString().toUpperCase();\
\
    }

运行结果:

image.png

定义访问限制和修改返回值:

@Around(value = "execution(* com.bjpowernode.s03.SomeServiceImpl.*(..))")\
    public Object myAround(ProceedingJoinPoint pjp)throws Throwable{\
        //取出目标方法的参数,进行判断,来决定是否调用目标方法以及增强功能\
        Object []args = pjp.getArgs();\
        if(args != null && args.length >1){\
            String name = (String) args[0];\
            if("张三".equals(name)){\
                System.*out*.println("前置通知实现........");\
                Object obj = pjp.proceed();\
                System.*out*.println("后置通知实现........");\
                return obj.toString().toUpperCase();\
            }\
        }\
        System.*out*.println("目标方法拒绝访问 !");\
        return null;\
    }\
}

测试类:

@Test\
public void test01(){\
    ApplicationContext ac = new ClassPathXmlApplicationContext("s03/applicationContext.xml");\
    SomeServiceImpl someService = (SomeServiceImpl) ac.getBean("someServiceImpl");\
    System.*out*.println(someService.getClass());\
    String s = someService.doSome("张三1",22);\
    System.*out*.println("在测试类中输出目标方法的返回值---"+s);\
}

运行结果:

image.png