想象你是一位快遞員,負責給一個大型社區送快遞。社區里有幾百戶人家,但只有特定家庭需要特殊服務:
- 普通快遞:直接放快遞柜
- 生鮮快遞:需要冷藏處理
- 貴重物品:需要本人簽收
- 藥品快遞:需要優先配送
@annotation
?就像你手中的智能標簽掃描器,它能精準識別每個包裹上的特殊標簽,讓你只對貼有特定標簽的包裹提供特殊服務。
一、核心概念:注解就是快遞標簽
1. 定義標簽(創建注解)
// 生鮮標簽
@Target(ElementType.METHOD) // 貼在方法上
@Retention(RetentionPolicy.RUNTIME) // 運行時可見
public @interface FreshDelivery {int storageTemp() default 4; // 冷藏溫度
}// 貴重物品標簽
public @interface ValuableItem {String signatureRequired() default "yes";
}
2. 貼標簽(方法添加注解)
public class DeliveryService {// 普通快遞(無標簽)public void deliverRegular(String address) {System.out.println("普通快遞送到" + address);}// 生鮮快遞(貼冷藏標簽)@FreshDelivery(storageTemp = 2)public void deliverFreshFood(String address) {System.out.println("生鮮送到" + address);}// 貴重物品(貼簽收標簽)@ValuableItempublic void deliverJewelry(String address) {System.out.println("珠寶送到" + address);}
}
三、@annotation
?就是你的智能掃描器
@Aspect
@Component
public class DeliveryAspect {// 掃描生鮮標簽@Before("@annotation(fresh)")public void handleFresh(FreshDelivery fresh) {System.out.println("啟用冷藏箱,溫度設置為: " + fresh.storageTemp() + "℃");}// 掃描貴重物品標簽@Around("@annotation(valuable)")public Object handleValuable(ProceedingJoinPoint pjp, ValuableItem valuable) {System.out.println("要求收件人出示身份證");System.out.println("需要簽收: " + valuable.signatureRequired());try {// 執行配送return pjp.proceed();} finally {System.out.println("已確認簽收,拍照存檔");}}
}
四、工作流程:精準服務
實際配送場景:
public static void main(String[] args) {DeliveryService service = getDeliveryService(); // 獲取代理對象service.deliverRegular("A棟101"); // 普通快遞// 輸出: 普通快遞送到A棟101service.deliverFreshFood("B棟202"); // 生鮮快遞// 輸出: // 啟用冷藏箱,溫度設置為: 2℃// 生鮮送到B棟202service.deliverJewelry("C棟303"); // 貴重物品// 輸出:// 要求收件人出示身份證// 需要簽收: yes// 珠寶送到C棟303// 已確認簽收,拍照存檔
}
五、為什么需要?@annotation
?
問題 | 無注解的解決方案 | 使用?@annotation ?的解決方案 |
---|---|---|
精準定位 | 按地址篩選:"B棟的都冷藏" | 直接掃描包裹標簽 |
差異化服務 | 所有生鮮統一4℃冷藏 | 根據標簽設置不同溫度 |
擴展性 | 新增藥品配送需修改篩選規則 | 只需新增藥品標簽 |
代碼耦合 | 配送服務需要知道處理邏輯 | 配送服務只貼標簽,不關心處理 |
六、@annotation
?的獨特優勢
? 精確制導:像激光制導導彈一樣精準定位
? ?
// 只處理帶@MedicalDelivery標簽的方法
@Around("@annotation(MedicalDelivery)")
參數傳遞:讀取標簽上的參數
@annotation(medical) // 獲取注解實例
int priority = medical.priority(); // 讀取優先級參數
動態啟用:通過標簽開關功能
// 只有帶@EnableLogging的方法才記錄日志
@Before("@annotation(EnableLogging)")
解耦設計:業務代碼只需聲明需求
// 業務方法只需關注自己需要什么
@FreshDelivery(storageTemp=5)
public void deliverDairy() {...}
七、對比其他定位方式
1. 按樓棟配送(包路徑匹配)
// 處理com.delivery.fresh包下所有方法
@Before("execution(* com.delivery.fresh..*(..))")
- 問題:包內可能有不需要冷藏的普通快遞
2. 按物品類型配送(接口匹配)
// 處理實現Perishable接口的類
@Before("within(com.delivery.Perishable+)")
3. 智能標簽掃描(@annotation
)
// 精確處理貼有@FreshDelivery標簽的方法
@Before("@annotation(FreshDelivery)")
八 、為什么它叫?@annotation
?
在Spring AOP中:
@annotation
?是一個切點指示符(Pointcut Designator)- 它專門用于匹配帶有特定注解的方法
- 語法:
@annotation(annotation-type)
// 掃描帶@SpecialService標簽的方法 @Before("@annotation(com.example.SpecialService)")
十、總結:@annotation
?的本質
它就像快遞員的智能標簽掃描器:
- 識別需求:掃描方法上的注解標簽
- 精準服務:只為帶標簽的方法提供增強
- 參數讀取:獲取標簽上的配置參數
- 解耦設計:業務代碼只需聲明需求,不關心實現