亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 spring 中防止來自控制器的 dao 調用

在 spring 中防止來自控制器的 dao 調用

九州編程 2023-07-28 16:20:43
我試圖避免來自控制器類的 dao 調用。如果調用是從服務包完成的,那么 dao 調用應該成功,否則我將拋出異常。我不想在dao類的每個方法中都寫這個邏輯,所以打算使用aspectj來攔截dao調用。如何防止控制器中的 dao 并僅允許服務類中的 dao 。我應該使用任何其他 api/approach 嗎?任何建議package com;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;@Aspect@Componentpublic class DaoAspect {    @Before(value = "execution(* com.dao.*.*(..))")    public void beforeAdvice( JoinPoint joinPoint) {        // here I want to know the caller package/class        // if its com.service allow ,if com.controller reject    }}
查看完整描述

1 回答

?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

我們首先要區分

  • AspectJ(快速、高效、無代理、更強大)和

  • Spring AOP(基于代理、委托模式、“輕AOP”、僅方法攔截)。

編譯時檢查調用代碼@DeclareError

當使用 AspectJ 并使用 AspectJ 編譯器重新編譯遺留庫(具有 AOP 增強功能的 Java 編譯器的直接替代品)時,@DeclareError如果發現來自錯誤的類或包模式的調用,您可以使用 AspectJ 使編譯失敗。這樣你就不需要任何昂貴的運行時檢查、反射或其他技巧。對于 Maven 構建,您可以使用 AspectJ Maven 插件。

這就是我的建議:在構建時檢測無效調用,修復代碼以使其能夠編譯并在運行時無憂無慮。

call()使用帶有切入點的AspectJ 加載時編織 (LTW) 進行運行時檢查

然而,如果您不想使用 AspectJ 編譯器(即使您標記了問題spectj而不是spring-aop)或者對調用代碼沒有編譯時影響,您仍然可以使用AspectJ 加載時編織(LTW )來自春天。如果您想避免創建異常的唯一目的是分析其調用堆棧以找到調用者,那么 Spring AOP 絕對不夠。相反,在完整的 AspectJ 中,有一個名為call()Spring AOP 的切入點。您可以通過 LTW 編織到調用代碼中,然后使用它EnclosingStaticPart來查找調用者。唯一需要注意的是,在 Spring 中,您可能會使用代理而不是直接調用,這可能會間接地擾亂調用者,但您可以嘗試一下。

這是純 Java + AspectJ 中的MCVE(不涉及 Spring):

DAO、服務、控制器:

package com.dao.ddd;


public class MyDao {

? public void doSomething() {

? ? System.out.println("Doing something in DAO");

? }

}

package com.service.sss;


import com.dao.ddd.MyDao;


public class MyService {

? public void doSomething() {

? ? System.out.println("Doing something in service");

? ? new MyDao().doSomething();

? }

}

package com.controller.ccc;


import com.dao.ddd.MyDao;


public class MyController {

? public void doSomething() {

? ? System.out.println("Doing something in controller");

? ? new MyDao().doSomething();

? }

}

package de.scrum_master.app;


import com.controller.ccc.MyController;

import com.service.sss.MyService;


public class Application {

? public static void main(String[] args) {

? ? // Allowed

? ? new MyService().doSomething();

? ? // Forbidden

? ? new MyController().doSomething();

? }

}

驅動程序應用:


package de.scrum_master.app;


import com.controller.ccc.MyController;

import com.service.sss.MyService;


public class Application {

? public static void main(String[] args) {

? ? // Allowed

? ? new MyService().doSomething();

? ? // Forbidden

? ? new MyController().doSomething();

? }

}

不帶方面的控制臺日志:


Doing something in service

Doing something in DAO

Doing something in controller

Doing something in DAO

實際上,列表行不應該被打印,因為從控制器到 DAO 的調用是被禁止的。


方面:


package de.scrum_master.aspect;


import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.JoinPoint.EnclosingStaticPart;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;


@Aspect

public class ContractEnforcerAspect {

? @Before("call(* com.dao..*(..))")

? public void beforeAdvice(JoinPoint joinPoint, EnclosingStaticPart enclosingStaticPart) {

? ? System.out.println("? Callee = " + joinPoint.getSignature());

? ? System.out.println("? Caller = " + enclosingStaticPart.getSignature());

? ? if (enclosingStaticPart.getSignature().getDeclaringType().getPackageName().startsWith("com.controller"))

? ? ? throw new RuntimeException("DAO must not be called from controller");

? }

}

控制臺日志與方面:


Doing something in service

? Callee = void com.dao.ddd.MyDao.doSomething()

? Caller = void com.service.sss.MyService.doSomething()

Doing something in DAO

Doing something in controller

? Callee = void com.dao.ddd.MyDao.doSomething()

? Caller = void com.controller.ccc.MyController.doSomething()

Exception in thread "main" java.lang.RuntimeException: DAO must not be called from controller

? ? at de.scrum_master.aspect.ContractEnforcerAspect.beforeAdvice(ContractEnforcerAspect.aj:17)

? ? at com.controller.ccc.MyController.doSomething(MyController.java:8)

? ? at de.scrum_master.app.Application.main(Application.java:11)


查看完整回答
反對 回復 2023-07-28
  • 1 回答
  • 0 關注
  • 133 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號