注記を使用したspringのaopで、メソッドで他のメソッドを呼び出すことができない(関数内部呼び出しでブロックできない)問題を解決します.


最近、プロジェクトにユーザーログを記録し、カスタム注釈を使用してaopブロックを行い、呼び出しクラスをブロックできる最初の方法を発見しました.方法で他の方法を呼び出すと、他の方法はブロックできません.クエリーを経て、aop自身の動的エージェントによるものであることがわかりました.以下、プロジェクトのコードを貼ります.
1、カスタム注記
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogController {
    String operationContent() default "";
}

2、springのaopコード
@Aspect
@Component
public class UserLogAspect {

    @Pointcut("@annotation(com.jingli.creditchain.service.userlog.LogController)")
    public void methodAspect() {

    }

    @SuppressWarnings("rawtypes")
    @After("methodAspect()")
    public void doAfter(JoinPoint joinPoint) {
        try {
            //      
            Object target = joinPoint.getTarget();
            //       
            String methodName = joinPoint.getSignature().getName();
            //       
            Class[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes();
            //         method
            Method method = target.getClass().getMethod(methodName, parameterTypes);
            String content = method.getAnnotation(LogController.class).operationContent();
            //        
            System.out.println("================="+content);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}

3、コントロール中の方法でブロックする
    @LogController(operationContent = "findApply")
    @RequestMapping(path = "/list", method = RequestMethod.POST)
    public List findApply(@RequestBody QueryInnerApplyVm query) {
        //    vm,            (          )
        QueryParam queryParam = queryInnerApplyVmToQueryParam(query);
        return applyService.findApply(queryParam)
            .stream()
            .filter(Objects::nonNull)
            .map(this::assignApplyVm)
            .collect(Collectors.toList());
    }


//    
@LogController(operationContent = "queryInnerApplyVmToQueryParam")
public QueryParam queryInnerApplyVmToQueryParam(QueryInnerApplyVm vm) {
    return new QueryParam();
}

4、テスト、印刷結果を見る
=================findApply

メソッドで呼び出された2番目のメソッドはブロックされていないことがわかります.
理由:
このクラスを呼び出すと、エージェントオブジェクトが呼び出され、エージェントクラスの内部コードはほぼ次のようになります.
private ApplyController applyController;

public List findApply(@RequestBody QueryInnerApplyVm query) {

    //    ,        ,           ,          ,    
           。       ,          ,       。
    QueryParam queryParam = applyController.queryInnerApplyVmToQueryParam(query);
       
}

5、コードの修正
ApplicationContextを取得し、コンテナからオブジェクトを取得し、そのオブジェクトにエージェントオブジェクトがあればエージェントオブジェクトを取得できます.
//   
@Component
public class BeanUtil implements ApplicationContextAware {
    private  static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(@NotNull ApplicationContext applicationContext){
        BeanUtil.applicationContext = applicationContext;
    }

    public static  T getBean(Class bean){
        return applicationContext.getBean(bean);
    }
}
    @LogController(operationContent = "findApply")
    @RequestMapping(path = "/list", method = RequestMethod.POST)
    public List findApply(@RequestBody QueryInnerApplyVm query) {
        QueryParam queryParam = BeanUtil.getBean(this.getClass()).queryInnerApplyVmToQueryParam(query);
    }

6、テスト
=================queryInnerApplyVmToQueryParam

=================findApply

2つ目の方法もブロックされた.
7、まとめ
Springはaopを使用して関数内部呼び出しを行うことをお勧めしません.呼び出した関数を別のクラスに書くことができます.しかし、これではコードが少し乱れてしまうので、私のプロジェクトで状況を見て、上の書き方が便利であれば、私はやはり上の方法で=.=
この问题は最初は私を困らせて、インターネットでこの问题を调べて大神解答があって、とても感谢して、同じく记录します.