日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Spring AOP 切面@Around注解的具體使用

作者:Jothan Zhong 更新時間: 2024-01-08 編程語言

@Around注解可以用來在調用一個具體方法前和調用后來完成一些具體的任務。

比如我們想在執行controller中方法前打印出請求參數,并在方法執行結束后來打印出響應值,這個時候,我們就可以借助于@Around注解來實現;

再比如我們想在執行方法時動態修改參數值等

類似功能的注解還有@Before等等,用到了Spring AOP切面思想,Spring AOP常用于攔截器、事務、日志、權限驗證等方面。

完整演示代碼如下:

需要說明的是,在以下例子中,我們即可以只用@Around注解,并設置條件,見方法run1();也可以用@Pointcut和@Around聯合注解,見方法pointCut2()和run2(),這2種用法是等價的。如果我們還想利用其進行參數的修改,則調用時必須用joinPoint.proceed(Object[] args)方法,將修改后的參數進行回傳。如果用joinPoint.proceed()方法,則修改后的參數并不會真正被使用。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import javax.persistence.EntityManager;
 
/**
 * 控制器切面
 *
 * @author lichuang
 */
 
@Component
@Aspect
public class ControllerAspect {
 
    private static final Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
 
    @Autowired
    private EntityManager entityManager;
 
    /**
     * 調用controller包下的任意類的任意方法時均會調用此方法
     */
    @Around("execution(* com.company.controller.*.*(..))")
    public Object run1(ProceedingJoinPoint joinPoint) throws Throwable {
        //獲取方法參數值數組
        Object[] args = joinPoint.getArgs();
        //得到其方法簽名
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //獲取方法參數類型數組
        Class[] paramTypeArray = methodSignature.getParameterTypes();
        if (EntityManager.class.isAssignableFrom(paramTypeArray[paramTypeArray.length - 1])) {
            //如果方法的參數列表最后一個參數是entityManager類型,則給其賦值
            args[args.length - 1] = entityManager;
        }
        logger.info("請求參數為{}",args);
        //動態修改其參數
        //注意,如果調用joinPoint.proceed()方法,則修改的參數值不會生效,必須調用joinPoint.proceed(Object[] args)
        Object result = joinPoint.proceed(args);
        logger.info("響應結果為{}",result);
        //如果這里不返回result,則目標對象實際返回值會被置為null
        return result;
    }
 
    @Pointcut("execution(* com.company.controller.*.*(..))")
    public void pointCut2() {}
 
    @Around("pointCut2()")
    public Object run2(ProceedingJoinPoint joinPoint) throws Throwable {
        //獲取方法參數值數組
        Object[] args = joinPoint.getArgs();
        //得到其方法簽名
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //獲取方法參數類型數組
        Class[] paramTypeArray = methodSignature.getParameterTypes();
        if (EntityManager.class.isAssignableFrom(paramTypeArray[paramTypeArray.length - 1])) {
            //如果方法的參數列表最后一個參數是entityManager類型,則給其賦值
            args[args.length - 1] = entityManager;
        }
        logger.info("請求參數為{}",args);
        //動態修改其參數
        //注意,如果調用joinPoint.proceed()方法,則修改的參數值不會生效,必須調用joinPoint.proceed(Object[] args)
        Object result = joinPoint.proceed(args);
        logger.info("響應結果為{}",result);
        //如果這里不返回result,則目標對象實際返回值會被置為null
        return result;
    }
}

原文鏈接:https://blog.csdn.net/qq_43985303/article/details/135362402

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新