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

Spring AOP入門:基於ProxyFactoryBean的代理實現完整示例

     編輯:Java 相關知識

Spring AOP 的最基礎實現方式是使用 ProxyFactoryBean 手動裝配代理、目標對象與通知。本文通過一個用戶管理業務場景,演示前置通知的配置與運行流程,幫助理解 AOP 底層機制。

一、業務接口與實現

// 數據訪問層
public interface UserDao {
    void addUser(String username, String password);
    void delUser(int id);
}

public class UserDaoImpl implements UserDao {
    @Override public void addUser(String u, String p) { System.out.println(u + " 用戶添加成功"); }
    @Override public void delUser(int id) { System.out.println("編號 " + id + " 用戶被刪除"); }
}

// 業務邏輯層
public interface UserBiz {
    void addUser(String username, String password);
    void delUser(int id);
}

public class UserBizImpl implements UserBiz {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) { this.userDao = userDao; }

    @Override public void addUser(String u, String p) { userDao.addUser(u, p); }
    @Override public void delUser(int id) { userDao.delUser(id); }
}

二、前置通知實現

import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;

public class LogAdvice implements MethodBeforeAdvice {
    private static final Logger logger = Logger.getLogger(LogAdvice.class);

    @Override
    public void before(Method method, Object[] args, Object target) {
        String cls = target.getClass().getName();
        String mtd = method.getName();
        logger.info("前置通知:" + cls + " 類的 " + mtd + " 方法開始執行");
    }
}

三、Spring XML 裝配

<beans xmlns="https://www.springframework.org/schema/beans"
       xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="https://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 目標對象 -->
    <bean id="userDao" class="com.xue.dao.UserDaoImpl"/>
    <bean id="userBiz" class="com.xue.dao.UserBizImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <!-- 通知 -->
    <bean id="logAdvice" class="com.xue.aop.LogAdvice"/>

    <!-- 代理工廠 -->
    <bean id="ub" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口 -->
        <property name="proxyInterfaces" value="com.xue.dao.UserBiz"/>
        <!-- 通知鏈 -->
        <property name="interceptorNames">
            <list><value>logAdvice</value></list>
        </property>
        <!-- 目標對象 -->
        <property name="target" ref="userBiz"/>
    </bean>
</beans>

四、測試驗證

public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserBiz biz = (UserBiz) ctx.getBean("ub"); // 獲取代理對象
        biz.addUser("zhangsan", "123");
        biz.delUser(1);
    }
}

五、運行輸出

[INFO ] [18:02:32] com.xue.aop.LogAdvice - 前置通知:com.xue.dao.UserBizImpl 類的 addUser 方法開始執行
zhangsan 用戶添加成功
[INFO ] [18:02:32] com.xue.aop.LogAdvice - 前置通知:com.xue.dao.UserBizImpl 類的 delUser 方法開始執行
編號 1 用戶被刪除

六、核心原理解析

  1. ProxyFactoryBean 實現 FactoryBean,getObject() 返回 JDK 動態代理(針對接口)或 CGLIB 代理(針對類)
  2. proxyInterfaces 指定代理實現的接口,target 指向被代理 Bean
  3. interceptorNames 列表中的 Bean 必須實現 Advice 子接口(MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice、MethodInterceptor 等)
  4. 調用 biz.addUser() 時,代理攔截 → 執行通知鏈 → 委派目標對象 → 返回結果

七、四種通知類型對比

通知類型接口執行時機典型用途
前置通知MethodBeforeAdvice方法調用前日志、權限檢查
後置通知AfterReturningAdvice方法正常返回後結果增強、緩存更新
環繞通知MethodInterceptor完全控制調用事務管理、性能監控
異常通知ThrowsAdvice方法拋出異常後異常處理、告警

八、現代替代方案

Spring 2.0+ 推薦使用 <aop:config> 或 @AspectJ 註解風格,配置更簡潔、可讀性更強。但理解 ProxyFactoryBean 有助於排查代理創建失敗、通知不生效等底層問題。

本示例展示了 Spring AOP 最原始的程式化配置方式,是掌握 AOP 核心概念的基石。

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