Spring AOP 配置看似正確,但 Advice (通知) 完全不被執行,通常源於以下幾點:
Advisor) 必須標註 @Component 或在 XML 中宣告 <bean id="advices" class="..."/>。execution(* com.sunyard.cpjbxxShow.action.*.*(..)) 需精確對應目標方法的套件、類別、方法簽名。檢查實際 Controller/Service 套件路徑是否一致。<aop:aspectj-autoproxy/> 或 XML 命名空間宣告不全。<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="https://www.springframework.org/schema/aop"
xsi:schemaLocation="...">
<!-- 1. 啟用 @AspectJ 自動代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 2. 定義 Advice Bean -->
<bean id="logAdvice" class="com.sunyard.advice.Advisor"/>
<!-- 3. 切面配置 -->
<aop:config>
<aop:aspect id="loggingAspect" ref="logAdvice">
<!-- 請務必確認此路徑與實際 Controller 套件完全一致 -->
<aop:pointcut id="controllerMethods"
expression="execution(public * com.sunyard.cpjbxxShow.action..*.*(..))"/>
<aop:before pointcut-ref="controllerMethods" method="before"/>
<aop:after pointcut-ref="controllerMethods" method="after"/>
<aop:after-throwing pointcut-ref="controllerMethods" method="exception"/>
</aop:aspect>
</aop:config>
</beans>
@Component // 或 XML 宣告
public class Advisor {
private static final Logger log = LoggerFactory.getLogger(Advisor.class);
public void before(JoinPoint jp) {
log.info("▶ 執行前: {}.{}", jp.getSignature().getDeclaringTypeName(), jp.getSignature().getName());
}
public void after(JoinPoint jp) {
log.info("■ 執行後: {}.{}", jp.getSignature().getDeclaringTypeName(), jp.getSignature().getName());
}
public void exception(JoinPoint jp) {
log.error("✖ 異常: {}.{} - {}", jp.getSignature().getDeclaringTypeName(), jp.getSignature().getName(), jp.getArgs());
}
}
Creating proxy for ... 字樣。execution(* *(..)) 測試是否為路徑問題。核心口訣:Bean 註冊到位、Pointcut 路徑精確、方法 public 非 final、外部呼叫觸發代理。