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

Spring 核心概念 AOP 詳解:XML 與 AspectJ 註解兩種配置實戰

     編輯:Java 綜合教學

Spring AOP 核心概念與實戰完整指南

AOP(Aspect Oriented Programming,面向切面編程)在不修改原有業務代碼前提下,為方法增加橫切關注點(日誌、事務、權限、效能監控等)。

一、核心術語

術語說明
Join Point(連接點)可插入增強的點,如方法呼叫、例外拋出
Pointcut(切入點)匹配 Join Point 的條件表達式
Advice(增強/通知)在切入點執行的具體邏輯
Aspect(切面)Pointcut + Advice 的模組化封裝
Weaving(織入)將 Aspect 應用到目標物件的過程

二、Schema 風格 XML 配置(傳統)

1. 目標介面與實作

public interface UserService {
    void addUser(User user);
    List<User> getAll();
}

public class UserServiceImpl implements UserService {
    private UserDao dao;
    public void setDao(UserDao dao) { this.dao = dao; }
    // 實作方法...
}

2. 定義增強類別

public class ServiceLogging {
    private Log log = LogFactory.getLog(getClass());
    public void beforeService() { log.info("AOP 方法被呼叫!"); }
}

3. applicationContext.xml 配置

<beans xmlns:aop="https://www.springframework.org/schema/aop" ...>
  <bean id="userDao" class="...UserDaoImpl"/>
  <bean id="userService" class="...UserServiceImpl">
    <property name="dao" ref="userDao"/>
  </bean>
  <bean id="serviceLogging" class="...ServiceLogging"/>

  <aop:config>
    <aop:pointcut id="servicePointcut"
        expression="execution(public void addUser(..))"/>
    <aop:aspect ref="serviceLogging">
      <aop:before method="beforeService" pointcut-ref="servicePointcut"/>
    </aop:aspect>
  </aop:config>
</beans>

三、五種增強類型

類型標籤執行時機典型用途
前置增強<aop:before>目標方法前權限檢查、日誌記錄
後置增強<aop:after-returning>正常返回後結果處理、快取更新
異常增強<aop:after-throwing>拋出異常時異常日誌、告警通知
最終增強<aop:after>最後執行(類 finally)資源清理、釋放鎖
環繞增強<aop:around>前後皆可控制事務管理、效能計時、快取攔截

環繞增強範例

public Object around(ProceedingJoinPoint pjp) throws Throwable {
    long start = System.currentTimeMillis();
    Object result = pjp.proceed(); // 執行目標方法
    System.out.println("耗時:" + (System.currentTimeMillis() - start) + "ms");
    return result;
}

四、切入點表達式常用模式

  • execution(public * com.pkg..*.*(..)):com.pkg 及子包所有公共方法
  • execution(* set*(..)):所有 setter 方法
  • execution(* com.pkg.Service.*(..)):Service 介面所有方法
  • @annotation(com.pkg.Loggable):標註特定註解的方法

五、AspectJ 註解風格(現代推薦)

1. 切面類別

@Aspect
public class AspectTest {
    @Before("execution(* com.jbit.ssh.service..*.*(..))")
    public void before() { System.out.println("前置增強"); }

    @After("execution(* com.jbit.ssh.service..*.*(..))")
    public void after() { System.out.println("最終增強"); }

    @AfterReturning(pointcut = "execution(* com.jbit.ssh.service..*.*(..))", returning = "ret")
    public void afterReturning(Object ret) { System.out.println("返回值:" + ret); }

    @AfterThrowing(pointcut = "execution(* com.jbit.ssh.service..*.*(..))", throwing = "ex")
    public void afterThrowing(Exception ex) { System.out.println("異常:" + ex.getMessage()); }

    @Around("execution(* com.jbit.ssh.service..*.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        return pjp.proceed();
    }
}

2. 啟用 AspectJ 自動代理

<aop:aspectj-autoproxy/>
<bean class="com.jbit.ssh.aop.AspectTest"/>

六、測試驗證

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = ac.getBean("userService", UserService.class);
service.addUser(new User());
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved