首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring AOP 兩大配置方式全解析:@AspectJ 註解 vs XML 命名空間

     編輯:Java 相關知識

前言

Spring AOP 支援兩種主流配置風格:基於 @AspectJ 註解(推薦,類型安全、IDE 友好)與傳統 XML 命名空間(舊項目常見、集中式管理)。本文以統一業務場景(用戶註冊服務加日誌切面)為例,完整演示兩種方式的配置細節、依賴引入、切點表達式寫法及驗證測試。

公共業務層代碼

// 領域模型
public class User { private String username, password; /* getter/setter */ }

// DAO 接口與實現
public interface UserDAO { void save(User user); }

@Component("u")
public class UserDAOImpl implements UserDAO {
    public void save(User user) { System.out.println("user saved"); }
}

// Service 層
@Component("userService")
public class UserService {
    @Resource(name="u") private UserDAO userDAO;
    public void add(User user) { userDAO.save(user); }
}

方式一:@AspectJ 註解配置(推薦)

1. Maven 依賴

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.x</version>
</dependency>

2. 切面類

@Aspect
@Component
public class LogInterceptor {
    @Pointcut("execution(public * com.bjsxt.service..*.add(..))")
    public void serviceAdd() {}

    @Before("serviceAdd()")
    public void before() { System.out.println("method start"); }

    @After("serviceAdd()")
    public void after() { System.out.println("method after"); }

    @AfterReturning("execution(public * com.bjsxt.dao..*.*(..))")
    public void afterReturn() { System.out.println("method afterReturning"); }

    @AfterThrowing("execution(public * com.bjsxt.dao..*.*(..))")
    public void afterThrow() { System.out.println("method afterThrowing"); }
}

3. Spring XML 啟用

<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:context="https://www.springframework.org/schema/context"
       xmlns:aop="https://www.springframework.org/schema/aop"
       xsi:schemaLocation="...
       https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.bjsxt"/>
    <aop:aspectj-autoproxy/>  <!-- 關鍵:啟用 @AspectJ 自動代理 -->
</beans>

方式二:XML 命名空間配置

切面類改為普通 POJO,移除 @Aspect、@Pointcut 等註解,僅保留業務方法(before()、after() 等)。

<beans ... xmlns:aop="https://www.springframework.org/schema/aop">
    <context:component-scan base-package="com.bjsxt"/>

    <bean id="logInterceptor" class="com.bjsxt.aop.LogInterceptor"/>

    <aop:config>
        <aop:pointcut id="serviceAddPointcut"
            expression="execution(public * com.bjsxt.service..*.add(..))"/>
        <aop:aspect id="logAspect" ref="logInterceptor">
            <aop:before method="before" pointcut-ref="serviceAddPointcut"/>
            <aop:after method="after" pointcut-ref="serviceAddPointcut"/>
            <aop:after-returning method="afterReturn" pointcut-ref="serviceAddPointcut"/>
            <aop:after-throwing method="afterThrow" pointcut-ref="serviceAddPointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

核心區別對比

維度@AspectJ 註解XML 配置
類型安全編譯期檢查切點表達式拼寫運行期解析,易拼寫錯誤
IDE 支援跳轉、重構、提示完善僅 XML 編輯器輔助
集中管理切面邏輯分散在類上所有切點、增強集中在 XML
適用場景新項目、團隊熟悉註解舊項目、運維需動態調整切點

切點表達式速查

  • execution(modifiers? ret-type declaring-type?name(param) throws?)
  • 通配符:*(任意返回類型/方法名/包)、..(任意參數/子包)。
  • 常用例子:execution(* com..service.*.*(..)) 匹配 service 包下所有公共方法。

驗證測試

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Autowired UserService userService;
    @Test public void test() { userService.add(new User()); }
}
// 輸出:method start → user saved → method afterReturning → method after

總結

新項目首選 @AspectJ 註解,代碼即配置,重構安全;老項目維護或需運維動態調整切點時,XML 仍有優勢。兩者可混用(XML 中 <aop:aspectj-autoproxy/> 會同時掃描註解切面)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved