JAVA同一クラス内メソッド呼び出しAOP解決メソッド

1660 ワード

1.問題現象
    @Around("execution(* com.unicom.hl.service.TowerPayService.processInsert(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
    	...
    }

一つの方法に対して切面定義が明確に行われていることがわかる.しかし、実行時には断面的な論理はありません.ビジネスコードの呼び出しは次のとおりです.
	//         ,             
	public Object insertPay(List list) {
		...
		processInsert_db(province, list);  //               
		...
	}

	//        
    @TargetDataSource
    public List processInsert_db(String province, List list) {
    	...
    }

2.原因分析
問題は、フェースメソッドprocessInsert_dbを呼び出すメソッドが同じクラス内であることである.他のクラスがprocessInsert_dbを直接呼び出す場合、接線論理が実行されます.AOPは既存のビジネスロジックを一度強化するため、既存のコードに基づいてclassファイルを生成する場合やclassにインストールするとJVM内にエージェントエージェントオブジェクトが生成され、エージェントオブジェクトは@Autowiredによって他のクラスの参照に注入されるため、他のクラスの呼び出し時に実際にエージェントオブジェクトが使用されるため、切面ロジックがトリガーされます.ただし、クラス内呼び出しの場合、エージェントオブジェクトではなくオブジェクト自体が使用されるため、接面論理は実行されません.
3.ソリューション
シナリオ1:コードによる解決
Spring bootの起動クラスに注記@EnableAspectJAutoProxy(exposeProxy=true)を追加すると、クラス内で呼び出されるときに次のようにエージェントオブジェクトを取得するので、元のオブジェクト自体ではなく、元のオブジェクトを呼び出す方法がルートになります.上の呼び出しを次のように変更します.
	public Object insertPay(List list) {
		...
		PayService service = AopContext.currentProxy() != null ? (PayService)AopContext.currentProxy() : this;
        List resultResponses = service.processInsert_db(province, subList);
		...
	}

シナリオ2:切断面を使用しない
接面を使わずに、論理をコードに直接書きます.あるいは他の融通性のある方法で実現されます.または、前のレイヤコードにこのエージェントオブジェクトを呼び出す方法