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

Spring IOC 容器進階:屬性注入全類型、組件掃描、生命周期與作用域控制

     編輯:Java 綜合教學

Spring IOC 容器進階:屬性注入全類型、組件掃描、生命周期與作用域控制

基於 Spring 3.2+ 版本,系統講解 IOC 容器的四大核心能力:多類型屬性注入、註解驅動組件掃描、Bean 作用域與生命周期控制、以及向註解配置遷移的最佳實踐。

一、屬性注入全類型實戰

1. 基礎類型與引用類型

<bean id="messageBean" class="com.example.MessageBean">
    <property name="moduleName" value="測試基本屬性注入"/>
    <property name="pageSize" value="5"/>
    <property name="username" value="#{jdbcProperties.username}"/> <!-- SpEL 表達式 -->
    <property name="password"><null/></property> <!-- 顯式注入 null -->
</bean>

2. 集合類型注入(四大集合全覆蓋)

<property name="someList">
    <list><value>北京</value><value>上海</value><value>廣州</value></list>
</property>
<property name="someSet">
    <set><value>James Gosling</value><value>Martin Fowler</value></set>
</property>
<property name="someMap">
    <map>
        <entry key="1001" value="Java基礎"/>
        <entry key="1002" value="Java Web"/>
    </map>
</property>
<property name="someProps">
    <props>
        <prop key="username">root</prop>
        <prop key="password">1234</prop>
    </props>
</property>

3. 集合 Bean 定義與引用式注入(複用配置)

<util:list id="commonList"><value>A</value><value>B</value></util:list>
<util:set id="commonSet"><value>X</value></util:set>
<util:map id="commonMap"><entry key="k1" value="v1"/></util:map>
<util:properties id="commonProps"><prop key="k1">v1</prop></util:properties>

<bean id="anotherBean" class="com.example.MessageBean">
    <property name="someList" ref="commonList"/>
    <property name="someSet" ref="commonSet"/>
    <property name="someMap" ref="commonMap"/>
    <property name="someProps" ref="commonProps"/>
</bean>

4. 外部屬性文件加載與 SpEL 注入

<util:properties id="jdbcProperties" location="classpath:db.properties"/>
<property name="username" value="#{jdbcProperties.username}"/>

二、組件掃描與註解驅動配置

1. 啟用掃描

<context:component-scan base-package="com.example"/>

2. 刻型註解語義

註解語義層級掃描優先級
@Component通用組件基礎
@Repository持久層(DAO)高(自動異常轉換)
@Service業務層高(事務邊界標識)
@Controller控制層高(Spring MVC 識別)

3. 實例:註解替代 XML 定義 Bean

@Component("exampleBean") // 默認 bean 名為 exampleBean
public class ExampleBean {
    public ExampleBean() { System.out.println("實例化 ExampleBean"); }
    public void execute() { System.out.println("執行業務邏輯"); }
}

三、Bean 作用域與生命周期精準控制

1. 作用域聲明

@Component
@Scope("prototype") // 或 singleton(默認)、request、session、application
public class PrototypeBean { ... }

驗證:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
PrototypeBean b1 = ctx.getBean(PrototypeBean.class);
PrototypeBean b2 = ctx.getBean(PrototypeBean.class);
System.out.println(b1 == b2); // prototype: false | singleton: true

2. 生命周期回調(JSR-250 標準註解)

@Component
@Scope("singleton")
public class LifecycleBean {
    @PostConstruct
    public void init() { System.out.println("初始化回調:資源獲取、連接池預熱"); }
    
    @PreDestroy
    public void destroy() { System.out.println("銷毀回調:資源釋放、連接關閉"); }
}

容器關閉觸發銷毀:

AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// ... 業務邏輯
ctx.close(); // 必須調用 close() 觸發 @PreDestroy,Web 環境由 ContextLoaderListener 自動管理

四、向純註解配置遷移指南

1. Java Config 替代 XML

@Configuration
@ComponentScan("com.example")
@PropertySource("classpath:db.properties")
public class AppConfig {
    @Bean
    public DataSource dataSource(@Value("${jdbc.url}") String url,
                                 @Value("${jdbc.user}") String user,
                                 @Value("${jdbc.password}") String pwd) {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl(url); ds.setUsername(user); ds.setPassword(pwd);
        return ds;
    }
}

2. 啟動方式

// 替換 ClassPathXmlApplicationContext
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

避坑檢查清單

  • ✅ @ComponentScan 基礎包配置正確,無遺漏子包
  • ✅ 集合注入使用 util: 命名空間,避免內聯定義重複
  • ✅ 原型 Bean 注入單例 Bean 時使用 @Lookup 或 ObjectFactory 避免單例污染
  • ✅ 非 Web 環境手動調用 ctx.close() 觸發銷毀回調
  • ✅ SpEL 表達式 #{...} 僅用於動態計算,靜態值直用 value

Spring IOC 的精髓在於聲明式配置與運行時元數據驅動。掌握全類型注入、組件掃描語義、作用域與生命周期控制,是從「會用 Spring」進階到「精通容器原理」的分水嶺。

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