前言
Spring框架自2003年兴起以来,已成为Java企业级开发的事实标准。它由Rod Johnson在其著作《Expert One-On-One J2EE Development and Design》中阐述的理念衍生而来,解决了企业应用开发的复杂性。本系列分为上下两篇,上篇聚焦于Spring最核心的控制反转(IoC) 和依赖注入(DI),涵盖XML配置、注解开发以及纯注解方式,并配有大量实战代码。
一、Spring框架概述
1.1 什么是Spring?
Spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,将面向接口的编程思想贯穿整个系统。Spring是一个轻量级 、一站式(JavaSE/EE full-stack)的开源框架。
1.2 Spring的核心架构
Spring的核心是 IoC(控制反转) 和 AOP(面向切面编程),构建了一个分层架构,允许开发者按需选择组件。
┌─────────────────────────────────────────┐
│ 表现层(Web层) │
├─────────────────────────────────────────┤
│ 业务层(Service层) │
├─────────────────────────────────────────┤
│ 持久层(DAO层) │
├─────────────────────────────────────────┤
│ Spring核心容器(IoC/AOP) │
└─────────────────────────────────────────┘
下图展示了Spring框架的经典分层架构,IoC和AOP作为底层基石,向上支撑着数据访问、Web层和业务逻辑层。

1.3 Spring的主要优点
-
解耦简化开发:Spring作为大工厂,管理对象创建和依赖关系。
-
AOP编程支持:方便实现权限拦截、运行监控等。
-
声明式事务:通过配置管理事务,无需手动编码。
-
方便测试:与JUnit整合,轻松测试。
-
集成优秀框架:支持Struts2、Hibernate、MyBatis等。
-
降低API难度:对JDBC、JavaMail等提供封装。
二、IoC控制反转核心技术
2.1 什么是IoC?
IoC(Inversion of Control)即控制反转,将对象的创建权力反转给Spring框架。它是一种设计原则,用于降低代码之间的耦合度。
-
传统方式 :
UserService service = new UserServiceImpl();(主动创建) -
IoC方式:由Spring工厂创建对象,我们被动获取。
2.2 IoC快速入门
步骤1:创建Maven工程,导入依赖
XML
xml
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
步骤2:编写接口与实现类
java
java
// UserService.java
package com.example.service;
public interface UserService {
void hello();
}
// UserServiceImpl.java
package com.example.service;
public class UserServiceImpl implements UserService {
@Override
public void hello() {
System.out.println("Hello IOC!!");
}
}
步骤3:编写Spring配置文件(applicationContext.xml)
XML
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userService" class="com.example.service.UserServiceImpl"/>
</beans>
步骤4:测试
java
java
@Test
public void testIoC() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) context.getBean("userService");
service.hello(); // 输出 Hello IOC!!
}
IoC容器获取Bean的流程如下图所示:

2.3 ApplicationContext工厂接口
-
ClassPathXmlApplicationContext:加载类路径下的配置文件。 -
FileSystemXmlApplicationContext:加载磁盘路径下的配置文件。
2.4 Bean管理的XML配置
| 属性 | 说明 |
|---|---|
id |
Bean的唯一标识(命名规范) |
class |
类的全路径 |
scope |
作用范围:singleton(默认单例)、prototype(多例)、request、session |
init-method / destroy-method |
生命周期回调方法 |
示例:
XML
xml
<bean id="userService" class="com.example.service.UserServiceImpl" scope="singleton" init-method="init" destroy-method="destroy"/>
2.5 实例化Bean的三种方式
2.5.1 默认无参构造(最常用)
XML
xml
<bean id="us" class="com.example.service.UserServiceImpl"/>
2.5.2 静态工厂方法
XML
java
public class StaticFactory {
public static UserService createUs() {
return new UserServiceImpl();
}
}
xml
<bean id="us" class="com.example.StaticFactory" factory-method="createUs"/>
2.5.3 实例工厂方法
XML
java
public class DFactory {
public UserService createUs() {
return new UserServiceImpl();
}
}
xml
<bean id="dfactory" class="com.example.DFactory"/>
<bean id="us" factory-bean="dfactory" factory-method="createUs"/>
三、DI依赖注入
3.1 什么是DI?
DI(Dependency Injection)即依赖注入 ,在Spring创建Bean时,动态地将依赖对象注入到Bean中。IoC是思想,DI是实现方式。
3.2 Setter方法注入
XML
java
public class OrderServiceImpl implements OrderService {
private OrderDao orderDao;
private String msg;
private int age;
// 必须提供setter方法
public void setOrderDao(OrderDao orderDao) { this.orderDao = orderDao; }
public void setMsg(String msg) { this.msg = msg; }
public void setAge(int age) { this.age = age; }
// 业务方法...
}
xml
<bean id="orderService" class="com.example.OrderServiceImpl">
<property name="orderDao" ref="orderDao"/>
<property name="msg" value="测试消息"/>
<property name="age" value="18"/>
</bean>
3.3 构造方法注入
XML
java
public class Car {
private String cname;
private Double money;
public Car(String cname, Double money) {
this.cname = cname;
this.money = money;
}
}
xml
<bean id="car" class="com.example.Car">
<constructor-arg name="cname" value="奔驰"/>
<constructor-arg name="money" value="400000"/>
</bean>
3.4 集合类型注入
支持数组、List、Set、Map、Properties等。
XML
xml
<bean id="collectionBean" class="com.example.CollectionBean">
<property name="strs">
<array><value>美美</value><value>小凤</value></array>
</property>
<property name="list">
<list><value>熊大</value><value>熊二</value></list>
</property>
<property name="map">
<map><entry key="aaa" value="老王"/></map>
</property>
<property name="properties">
<props><prop key="username">root</prop></props>
</property>
</bean>
三种注入方式关系图

四、多配置文件加载
方式一:在主配置文件中导入
xml
<import resource="applicationContext2.xml"/>
方式二:工厂同时加载多个
java
ApplicationContext ac = new ClassPathXmlApplicationContext("app1.xml", "app2.xml");
五、Spring整合JDBC实战(IoC+DI综合案例)
5.1 数据库准备
sql
sql
CREATE DATABASE spring_db;
USE spring_db;
CREATE TABLE account (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(40),
money DOUBLE
);
INSERT INTO account VALUES (NULL,'aaa',1000),(NULL,'bbb',1000);
5.2 依赖(添加Druid和MySQL驱动)
XML
xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
5.3 实体类、DAO、Service代码(省略getter/setter)
Account.java
java
java
public class Account {
private Integer id;
private String name;
private Double money;
// 构造、getter、setter、toString
}
AccountDao接口与实现
java
java
public interface AccountDao {
List<Account> findAll();
}
public class AccountDaoImpl implements AccountDao {
private DataSource dataSource;
public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; }
@Override
public List<Account> findAll() {
// 使用dataSource获取连接,执行查询,封装返回
// 代码略(详见PDF)
}
}
AccountService接口与实现
java
java
public interface AccountService {
List<Account> findAll();
}
public class AccountServiceImpl implements AccountService {
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; }
@Override
public List<Account> findAll() {
return accountDao.findAll();
}
}
5.4 配置文件(整合所有)
XML
xml
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_db"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="accountDao" class="com.example.dao.AccountDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="accountService" class="com.example.service.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
5.5 测试
java
java
@Test
public void testFindAll() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountService service = ac.getBean(AccountService.class);
List<Account> list = service.findAll();
list.forEach(System.out::println);
}
六、IOC注解方式

6.1 快速入门
在类上添加@Component(或@Service、@Repository、@Controller),并在配置文件中开启注解扫描。
java
java
@Component("us")
public class UserServiceImpl implements UserService {
public void hello() { System.out.println("Hello IOC注解..."); }
}
xml
<context:component-scan base-package="com.example"/>
测试时直接通过id获取。
6.2 常用注解详解
| 注解 | 作用 |
|---|---|
@Component |
普通类标记为Bean |
@Controller |
表现层 |
@Service |
业务层 |
@Repository |
持久层 |
@Value |
注入基本类型值 |
@Autowired |
按类型自动装配 |
@Qualifier |
与@Autowired配合,按名称注入 |
@Resource |
JSR-250,按名称注入 |
@Scope |
作用范围 |
@PostConstruct |
初始化方法 |
@PreDestroy |
销毁方法 |
示例:
java
java
@Service
@Scope("singleton")
public class Car {
@Value("大奔")
private String cname;
@Autowired
private Person person;
@PostConstruct
public void init() { System.out.println("初始化"); }
}
6.3 纯注解方式(无XML)
配置类
java
java
@Configuration
@ComponentScan("com.example")
@Import(OtherConfig.class)
public class SpringConfig {
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql:///spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}
测试
java
java
ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
Order order = ac.getBean(Order.class);
七、Spring整合JUnit单元测试
7.1 配置文件方式
java
java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestDemo {
@Autowired
private UserService userService;
@Test
public void test() { userService.hello(); }
}
7.2 纯注解方式
java
java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class TestDemo {
@Autowired
private UserService userService;
@Test
public void test() { userService.hello(); }
}
总结
本篇详细介绍了Spring框架的IoC控制反转 和DI依赖注入 ,从XML配置到注解再到纯注解,并通过整合JDBC的实战案例加深理解。掌握了这些内容,您就打下了Spring的坚实基础。下篇我们将深入AOP面向切面编程 、事务管理 和JDBC模板等高级特性,敬请期待。