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

Spring IOC 與 AOP 核心原理深度剖析

     編輯:Java 綜合教學

Spring 核心價值

  • 降低組件耦合,實現分層解耦
  • 提供事務管理、訊息服務等容器級服務
  • 支援單例模式、AOP(權限攔截、監控)、輔助類加速開發
  • 整合主流框架、低侵入、獨立於應用伺服器、DI 簡化業務替換、高度開放不強制依賴

DI(依賴注入)= IOC(控制反轉)

傳統模式:調用者主動 new 被調用者。Spring 模式:容器負責創建被調用者並注入調用者,實現「控制反轉」。兩種注入方式:Setter 注入(直觀自然)與建構子注入(可控制依賴順序)。

Setter 注入完整範例

實體類

public class Happy {
    private String happyInfo;
    public void happy() { System.out.println(happyInfo); }
    // getter/setter...
}

applicationContext.xml

<bean id="happy" class="cn.wgy.day_01.entity.Happy">
    <property name="happyInfo" value="中秋快樂"/>
</bean>

測試類

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Happy happy = (Happy) ctx.getBean("happy");
happy.happy();

BeanFactory vs ApplicationContext

特性BeanFactoryApplicationContext
國際化不支援支援 (MessageSource)
事件機制無完整事件發布/監聽
資源載入無實現 ResourceLoader
Web 支援程式化建立聲明式 + ContextLoaderListener
Bean 載入延遲載入啟動時一次性載入(早發現錯誤)
後處理器註冊手動自動

生產環境建議使用 ApplicationContext。

建構子注入與 p 命名空間注入

<bean id="user1" class="cn.wgy.day01.entity.User">
    <constructor-arg index="0" type="java.lang.String" value="Promise"/>
    <constructor-arg index="1" type="java.lang.String" value="Promise@163.com"/>
</bean>

<!-- p 命名空間 -->
<beans xmlns:p="https://www.springframework.org/schema/p" ...>
    <bean id="user" class="..." p:username="Promise" p:dao-ref="dao"/>
</beans>

集合、null、空字串注入

<property name="names"><list><value>A</value><value>B</value></list></property>
<property name="address"><set><value>北京</value></set></property>
<property name="map"><map><entry key="k"><value>v</value></entry></map></property>
<property name="hobbies"><props><prop key="f">足球</prop></props></property>
<property name="email"><value></value></property> <!-- 空串 -->
<property name="email"><null/></property>          <!-- null -->

AOP 核心概念

  • 補充 OOP:OOP 靜態抽象類,AOP 動態抽象執行流程切面。
  • 兩大特徵:步驟隔離性、原始碼無關性。
  • Spring AOP 兩大體現:聲明式事務、自定義切面。

AOP 實戰:前置/後置/環繞/異常增強

1. 介面實現類

public class LoggerBefore implements MethodBeforeAdvice { ... }
public class LoggerAfter implements AfterReturningAdvice { ... }
public class AroundLog implements MethodInterceptor { ... }
public class ErrorLog implements ThrowsAdvice { ... }

2. XML 配置(ProxyFactoryBean 方式)

<bean id="biz" class="...UserBiz"><property name="dao" ref="dao"/></bean>
<bean id="loggerBefore" class="...LoggerBefore"/>
<bean id="loggerAfter" class="...LoggerAfter"/>
<bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetName" value="biz"/>
    <property name="interceptorNames" value="loggerBefore,loggerAfter"/>
</bean>

3. Advisor 靈活控制切點

<bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
    <property name="advice" ref="around"/>
    <property name="mappedNames" value="delete"/>
</bean>
<bean id="regex" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <property name="advice" ref="around"/>
    <property name="pattern" value=".*do.*"/>
</bean>

動態代理底層原理

JDK 動態代理

  • 要求目標類實現介面。
  • 核心:Proxy.newProxyInstance(classLoader, interfaces, invocationHandler)。
  • InvocationHandler.invoke(proxy, method, args) 中攔截、增強、反射調用目標方法。

CGLIB 動態代理

  • 針對類(無介面也可),透過字節碼生成子類覆寫方法。
  • 核心:Enhancer.setSuperclass(clazz).setCallback(methodInterceptor).create()。
  • 效能:CGLIB 呼叫效能優於 JDK,但創建代理較慢;單例適合 CGLIB,原型適合 JDK。
  • 限制:無法代理 final 方法/類。

Spring 整合選擇

  • 目標有介面 → 預設 JDK 動態代理。
  • 目標無介面或強制 <aop:aspectj-autoproxy proxy-target-class="true"/> → CGLIB。

BeanFactory類圖 ApplicationContext類圖 AOP介面 AfterReturningAdvice MethodBeforeAdvice LoggerBefore MethodInterceptor AroundLog ThrowsAdvice ErrorLog ErrorLog2 JDK代理結構 Proxy類 InvocationHandler Method Method2 Enhancer Enhancer2 Enhancer3

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