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

Spring 入門核心:IoC 容器、依賴注入、XML 與註解雙模式配置實戰

     編輯:Java 綜合教學

Spring 核心思想:控制反轉與依賴注入

概念本質解決問題
IoC (Inversion of Control)對象創建權從應用代碼移交給容器解耦:類不再負責依賴的實例化
DI (Dependency Injection)容器在創建對象時注入依賴賦值:構造器/Setter/字段注入

兩者描述同一過程的不同視角:容器管理對象生命週期與依賴關係。

獲取 IoC 容器

// 1. ClassPathXmlApplicationContext (XML 配置)
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

// 2. AnnotationConfigApplicationContext (純註解配置)
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

// 3. Web 環境:ContextLoaderListener 自動啟動,Controller 中 @Autowired 直接可用

配置模式一:XML 配置 (傳統、外部化)

Bean 定義與屬性注入

<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">

    <!-- 1. Setter 注入 -->
    <bean id="student" class="com.example.Student">
        <property name="id" value="1"/>
        <property name="name" value="張三"/>
        <property name="age" value="20"/>
    </bean>

    <!-- 2. 構造器注入 -->
    <bean id="student2" class="com.example.Student">
        <constructor-arg name="id" value="2"/>
        <constructor-arg name="name" value="李四"/>
    </bean>

    <!-- 3. 引用其他 Bean (ref) -->
    <bean id="userDao" class="com.example.dao.UserDaoImpl"/>
    <bean id="userService" class="com.example.service.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>

    <!-- 4. 生命週期回調 -->
    <bean id="student3" class="com.example.Student" 
          init-method="init" destroy-method="destroy">
        <property name="name" value="王五"/>
    </bean>
</beans>

配置模式二:註解配置 (現代、主流)

1. 啟用組件掃描

<beans xmlns:context="https://www.springframework.org/schema/context"
       xsi:schemaLocation="...
       https://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.example"/>
    <!-- 等價於  + 掃描 -->
</beans>

或純 Java 配置:

@Configuration
@ComponentScan("com.example")
public class AppConfig { }

2. 組件註解 (四大金剛)

註解語義層級說明
@Component通用泛用組件,無特定業務含義
@Repository持久層DAO,自動轉換數據訪問異常
@Service業務層Service,標識業務邏輯組件
@Controller表現層SpringMVC 控制器,配合 @RequestMapping

本質上都是 @Component,語義化便於分層與 AOP 切點匹配。

3. 依賴注入註解

@Service
public class UserServiceImpl implements UserService {
    // 1. 字段注入 (簡潔但不利測試)
    @Autowired
    private UserDao userDao;

    // 2. 構造器注入 (推薦:不可變、易測試、必要依賴明確)
    private final UserDao userDao;
    @Autowired  // 單構造器可省略
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    // 3. Setter 注入 (可選依賴)
    private UserDao userDao;
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

4. 限定注入 (@Qualifier / @Primary)

@Repository("mysqlDao")
public class MySqlUserDao implements UserDao { }

@Repository("oracleDao")
@Primary  // 默認首選
public class OracleUserDao implements UserDao { }

@Service
public class UserServiceImpl {
    @Autowired
    @Qualifier("mysqlDao")  // 強制指定
    private UserDao userDao;
}

5. 作用域 (@Scope)

作用域含義Web 環境
singleton (默認)容器中單例單例
prototype每次獲取新實例每次請求新實例
request-每個 HTTP 請求一個實例
session-每個 HTTP Session 一個實例
application-每個 ServletContext 一個實例

XML vs 註解:如何選擇?

維度XML註解
侵入性零侵入 (POJO)需引入 Spring 註解
可讀性集中式,適合大型團隊分散在代碼中,IDE 支持好
重構友好修改配置文件重構工具自動更新
環境隔離多套配置文件切換Profile + @Conditional
趨勢維護模式主流、Spring Boot 默認

建議:新項目首選註解 + Java Config;基礎設施類 (DataSource、TransactionManager) 可用 XML/Java Config 集中管理。

實戰 Demo:分層架構注入鏈

// Dao
@Repository
public class UserDaoImpl implements UserDao { ... }

// Service
@Service
public class UserServiceImpl implements UserService {
    private final UserDao userDao;
    public UserServiceImpl(UserDao userDao) { this.userDao = userDao; }
    public User login(String u, String p) { return userDao.findByUsername(u); }
}

// Controller
@Controller
@RequestMapping("/user")
public class UserController {
    private final UserService userService;
    public UserController(UserService userService) { this.userService = userService; }

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password, Model model) {
        User user = userService.login(username, password);
        if (user != null) { model.addAttribute("user", user); return "welcome"; }
        return "login";
    }
}

總結

  • IoC 容器管理 Bean 生命週期,DI 實現依賴賦值
  • 構造器注入 > Setter 注入 > 字段注入
  • 註解配置為主流,XML 保留基礎設施配置
  • 掌握 @Autowired、@Qualifier、@Primary、@Scope 核心註解
  • 理解 singleton/prototype/request/session 作用域差異

Spring 核心就這麼簡單:容器負責 new,你負責用。

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