Spring 3.0 教程:经典 Java EE 开发框架
Spring 3.0 发布于 2009 年,是 Spring 框架发展史上的一个重要里程碑,它极大地简化了 Java EE 开发,引入了注解驱动的开发模式,使得配置更加简洁,开发效率大大提高,虽然现在 Spring 5.x 和 Spring Boot 已经成为主流,但理解 Spring 3.0 的核心思想对于掌握整个 Spring 生态至关重要。
为什么学习 Spring 3.0?
- 理解 Spring 的核心思想:Spring 3.0 完整地体现了 Spring 的两大核心:控制反转 和 面向切面编程,学习它是理解现代 Spring 框架的基础。
- 经典配置模式:Spring 3.0 同时支持 XML 配置和注解配置,通过学习它,你可以清晰地了解 Spring 框架是如何在代码和配置之间进行权衡的,这对于维护遗留项目非常有帮助。
- 轻量级与强大功能的结合:Spring 3.0 在保持轻量级的同时,提供了强大的事务管理、数据访问集成、Web MVC 等功能,是“小而美”和“大而全”的完美结合。
核心概念:IoC (控制反转) 与 DI (依赖注入)
这是 Spring 的灵魂,必须首先理解。
-
控制反转:是一种设计思想,就是将对象的创建和管理的权利从代码本身转移给一个外部容器(即 Spring IoC 容器)。
- 没有 IoC 时:你的代码需要
new出它所依赖的对象,代码之间耦合度高。 - 有 IoC 时:你的代码只需要定义它需要“做什么”(依赖什么),而“怎么做”(如何创建依赖对象)交给 Spring 容器。
- 没有 IoC 时:你的代码需要
-
依赖注入:是 IoC 思想的一种具体实现方式,即 Spring 容器在创建对象时,自动将对象所需要的其他依赖对象实例注入(传递)进来。
举个例子:
假设有一个 UserService 类,它需要 UserDao 来操作数据库。
// 1. 定义接口和实现
public interface UserDao {
void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("User data saved to database.");
}
}
// 2. 定义 Service,并持有 Dao 的引用
public class UserService {
// 依赖 UserDao
private UserDao userDao;
// 通过 setter 方法注入依赖
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void saveUser() {
userDao.save();
}
}
在没有 Spring 的情况下,你需要这样使用:
UserService userService = new UserService(); UserDao userDao = new UserDaoImpl(); userService.setUserDao(userDao); // 手动注入 userService.saveUser();
有了 Spring 的 DI,你只需要在配置文件中告诉 Spring:
“请创建一个 UserService 实例,并将 UserDaoImpl 实例注入给它”,然后你就可以直接使用 UserService 了,无需关心 UserDao 的创建。
Spring 3.0 的核心模块
Spring 框架由多个模块组成,你可以按需引入。
| 模块 | 功能描述 |
|---|---|
| Core Container | 核心容器,包括 BeanFactory 和 ApplicationContext,这是 Spring 的基础,负责创建和管理 Bean。 |
| AOP | 面向切面编程,允许你定义方法拦截器和切点,将功能(如日志、事务)与业务逻辑解耦。 |
| DAO / Data Access | 数据访问,提供了对 JDBC、ORM 框架(如 Hibernate)的统一抽象和简化。 |
| OXM | 对象/XML 映射,支持将对象与 XML 数据进行转换。 |
| Web / Web MVC | Web 层,提供了基于 Servlet 的 Web MVC 框架,是构建 Web 应用的核心。 |
| Transaction | 事务管理,为 Java EE 应用提供了声明式和编程式的事务管理。 |
环境搭建
-
下载 Spring 3.0 JAR 包
- 访问 Spring 官方历史版本下载页面。
- 我们需要下载核心库
spring-core-3.0.5.RELEASE.jar和上下文库spring-context-3.0.5.RELEASE.jar,实际项目中,你通常会下载一个dist目录下的spring-framework-3.0.5.RELEASE-with-dependencies.zip,里面包含了所有需要的 JAR。
-
创建 Java 项目
- 在你的 IDE(如 Eclipse, IntelliJ IDEA)中创建一个新的 Java 项目。
- 将下载的 JAR 包添加到项目的
lib目录,并添加到构建路径中。
-
日志配置 (可选但推荐)
- Spring 依赖日志框架,如 Log4j 或 Commons Logging,我们添加
commons-logging-1.1.1.jar并创建一个log4j.properties文件来方便查看日志信息。
- Spring 依赖日志框架,如 Log4j 或 Commons Logging,我们添加
第一个 Spring 程序:Hello World
我们将通过一个简单的例子来演示 XML 配置 和 注解配置 两种方式。
XML 配置 (经典方式)
创建 JavaBean
// src/com/example/HelloWorld.java
package com.example;
public class HelloWorld {
private String message;
public void setMessage(String message) {
this.message = message;
}
public void sayHello() {
System.out.println(message);
}
}
创建 Spring 配置文件
在 src 目录下创建 applicationContext.xml 文件,这是 Spring 的“心脏”。
<!-- src/applicationContext.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-3.0.xsd">
<!-- 1. 定义一个 Bean -->
<!-- id: Bean 在容器中的唯一标识 -->
<!-- class: Bean 的全限定类名 -->
<bean id="helloWorld" class="com.example.HelloWorld">
<!-- 2. 属性注入 -->
<!-- name: 属性名 -->
<!-- value: 属性值 -->
<property name="message" value="Hello, Spring 3.0 World!"/>
</bean>
</beans>
编写测试代码
// src/com/example/Test.java
package com.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// 1. 创建 Spring IoC 容器
// 读取 classpath 下的 applicationContext.xml 文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 从容器中获取 Bean
HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
// 3. 调用 Bean 的方法
helloWorld.sayHello(); // 输出: Hello, Spring 3.0 World!
}
}
运行 Test.java,你将在控制台看到预期的输出,恭喜,你已经成功运行了第一个 Spring 程序!
注解配置 (Spring 3.0 主推方式)
Spring 3.0 大力推广注解,以减少 XML 配置。
开启注解支持
修改 applicationContext.xml,添加 <context:annotation-config/>。
<!-- src/applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 开启注解支持,让 Spring 容器能够扫描 @Component 等注解 -->
<context:annotation-config/>
<!-- (可选) 扫描指定包下的所有带有 @Component 注解的类,并注册为 Bean -->
<context:component-scan base-package="com.example"/>
</beans>
修改 JavaBean,使用注解
// src/com/example/HelloWorld.java
package com.example;
import org.springframework.stereotype.Component;
// @Component 告诉 Spring,这个类是一个 Bean,默认的 id 是 "helloWorld" (类名首字母小写)
@Component
public class HelloWorld {
private String message;
// @Autowired 用于自动注入,Spring 会寻找类型匹配的 Bean (这里是 String) 并注入。
// 对于基本类型和 String,我们通常使用 @Value 来注入值。
@Value("Hello, Spring 3.0 with Annotation!")
public void setMessage(String message) {
this.message = message;
}
public void sayHello() {
System.out.println(message);
}
}
测试代码不变
// src/com/example/Test.java // ... (代码同上)
运行结果相同,你会发现,XML 配置变得非常简洁,大部分工作都通过注解完成了。
Spring 3.0 常用注解总结
| 注解 | 作用 | 示例 |
|---|---|---|
@Component |
通用注解,用于将类声明为 Spring Bean。 | @Component public class MyService {} |
@Repository |
用于数据访问层(DAO),功能同 @Component,并具备自动翻译异常的能力。 |
@Repository public class UserDaoImpl {} |
@Service |
用于业务逻辑层(Service),功能同 @Component。 |
@Service public class UserServiceImpl {} |
@Controller |
用于 Spring MVC 的控制器层,功能同 @Component。 |
@Controller public class MyController {} |
@Autowired |
自动注入,默认按类型进行注入。 | @Autowired private UserDao userDao; |
@Qualifier |
与 @Autowired 配合使用,当有多个同类型 Bean 时,按名称注入。 |
@Autowired @Qualifier("userJdbcDao") private UserDao userDao; |
@Value |
用于注入基本类型、String 或 SpEL 表达式的值。 | @Value("some value") 或 @Value("#{config['timeout']}") |
@Resource |
JSR-250 规范的注解,默认按名称注入,找不到则按类型注入。 | @Resource private UserDao userDao; |
@Configuration |
声明该类是一个配置类(Spring 3.0 引入,但更常用于 Spring 3.1+)。 | @Configuration public class AppConfig {} |
@Bean |
在配置类中,声明一个方法返回一个 Bean,并交由 Spring 管理。 | @Bean public DataSource dataSource() { ... } |
总结与展望
Spring 3.0 通过 IoC/DI 和 AOP 两大支柱,极大地提升了 Java 开发的灵活性和可维护性,它引入的注解驱动模式,标志着 Spring 开发进入了一个新的时代,为后续 Spring Boot 的“约定优于配置”思想铺平了道路。
虽然现在 Spring 3.0 已经过时,但它所包含的核心概念和设计模式是永恒的,掌握了它,再学习 Spring 4.0, 5.0 以及 Spring Boot,你会发现它们一脉相承,只是配置方式更加自动化和便捷。
学习建议:
- 动手实践上述所有示例,特别是 XML 和注解两种配置方式。
- 深入理解 IoC 容器的工作原理,它是 Spring 的基石。
- 学习 AOP 的基本概念,了解
@Aspect,@Before,@After等注解的使用。 - 尝试整合 MyBatis 或 Hibernate,体验 Spring 的数据访问集成能力。
- 尝试编写一个简单的 Spring MVC 应用,感受 Web 层的开发流程。
