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

Spring AOP 代理機制實戰:基於 ProxyFactoryBean 的方法前置增強完整範例

     編輯:Java 相關知識

Spring AOP 核心在於代理模式:為目標物件建立代理,在方法調用前後織入橫切關注點(日誌、事務、安全等)。本文以 ProxyFactoryBean 為例,示範如何透過 XML 配置實現 MethodBeforeAdvice(方法前置增強),並解析關鍵組件與運行流程。

核心組件速覽

組件角色關鍵介面/類別
目標物件被代理的業務邏輯實現實現業務介面的 POJO
增強橫切邏輯(前置、後置、環繞、拋異常、引介)MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor...
切點定義「在哪些方法」織入增強Pointcut, PointcutAdvisor
代理工廠生成代理物件的核心ProxyFactoryBean (XML), ProxyFactory (程式化)

完整實戰範例:方法前置日誌增強

1. 定義業務介面與實現

package com.example.aop;

public interface HelloService {
    void sayHello(String name);
}

public class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello(String name) {
        System.out.println("Hello, " + name);
    }
}

2. 實現 MethodBeforeAdvice(前置增強)

package com.example.aop;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class LoggingBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("[LOG] 方法調用: " + method.getName() + ", 參數: " + Arrays.toString(args));
    }
}

3. Spring XML 配置 (advice-config.xml)

<?xml version="1.0" encoding="UTF-8"?>
<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 -->
    <bean id="helloService" class="com.example.aop.HelloServiceImpl" />

    <!-- 增強 Bean -->
    <bean id="loggingBeforeAdvice" class="com.example.aop.LoggingBeforeAdvice" />

    <!-- 代理工廠 Bean -->
    <bean id="helloServiceProxy"
          class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理實現的介面 (JDK 動態代理) -->
        <property name="proxyInterfaces">
            <value>com.example.aop.HelloService</value>
        </property>
        <!-- 目標物件 -->
        <property name="target" ref="helloService" />
        <!-- 攔截器/增強鏈 -->
        <property name="interceptorNames">
            <list>
                <value>loggingBeforeAdvice</value>
            </list>
        </property>
    </bean>
</beans>

4. 測試類

package com.example.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopDemo {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("advice-config.xml");
        HelloService proxy = (HelloService) ctx.getBean("helloServiceProxy");
        proxy.sayHello("Spring AOP");
    }
}

5. 運行結果

[LOG] 方法調用: sayHello, 參數: [Spring AOP]
Hello, Spring AOP

關鍵配置屬性解析 (ProxyFactoryBean)

屬性說明備註
proxyInterfaces代理實現的介面清單若目標類實現介面,使用 JDK 動態代理;否則需 proxyTargetClass=true 強制 CGLIB
target目標物件引用可引用同一容器內的 Bean
interceptorNames攔截器/增強 Bean 名稱清單順序決定執行順序;支援 Advisor、Advice、MethodInterceptor
proxyTargetClass強制使用 CGLIB 代理類而非介面預設 false;目標類無介面或需代理具體方法時設 true
optimize優化代理生成 (CGLIB)預設 false
frozen凍結代理配置,禁止運行時修改預設 false

進階:從 XML 走向註解 (@AspectJ)

現代 Spring 專案推薦使用 @Aspect、@Before、@Pointcut 註解配合 @EnableAspectJAutoProxy,優勢在於:

  • 類型安全、IDE 支援完整(重構、查找引用)。
  • 切點表達式強大(execution、within、args、@annotation 等)。
  • 與 Spring Boot 自動配置無縫整合。

等價註解寫法:

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.aop.HelloService.*(..))")
    public void logBefore(JoinPoint jp) {
        System.out.println("[LOG] " + jp.getSignature() + " args=" + Arrays.toString(jp.getArgs()));
    }
}

總結

ProxyFactoryBean 是 Spring 早期 AOP 配置的核心,透過 proxyInterfaces、target、interceptorNames 三大屬性組裝代理。理解其運作原理,有助於深入掌握 Spring AOP 底層機制。現代開發請優先採用 @AspectJ 註解風格,享受更優雅、類型安全的切面程式設計體驗。

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