本次练习基于how2j和课本,初步认识Spring。
以后我每周只写一篇Web的博客,所以的作业内容会在这篇博客中持续更新。。。
- 一、Spring基础
- 1.Spring概述:
- 2.Sring组成:
- 3.BeanFactory:
- 4.控制反转:
- 5.依赖注入:
- 6.JavaBean与Spring的Bean:
- 7.Java的一般程序的生命周期与SpringBean的生命周期:
- (1)Java程序的生命周期:
- (2)SpringBean的生命周期:
- (3)Java程序的生命周期与SpringBean的生命周期的区别和联系:
- (4)JVM(Java虚拟机):
- 8.Java的一般容器与Spring中的容器:
- 9.耦合和内聚:
- 10.持久化:
- 二、第一个基于Spring的程序:
- (1)创建一个`Java Project`
- (2)新建一个`lib`文件夹:
- (3)配置环境:
- (4)配置文件:
- (5)实体类:
- (6)测试类:
- (7)运行查看:
一、Spring基础
1.Spring概述:
Spring框架是一个开源的Java企业应用程序开发框架,它提供了一系列的解决方案,帮助开发者在开发企业级应用时更加简单、高效、安全。Spring框架主要由IOC容器、AOP、数据访问、Web开发等模块组成。
举个例子,假设我们要开发一个Web应用,需要连接数据库并进行数据操作。使用Spring框架,我们可以使用Spring的IOC容器来管理对象的创建和依赖关系,使用Spring的数据访问模块来连接数据库并进行数据操作,同时还可以使用Spring的Web开发模块来快速开发Web应用。这样,我们可以更加高效、简单地开发出一个功能完善的Web应用。
2.Sring组成:
-
SpringCore模块:提供Spring框架的基础功能,如=依赖注入和控制反转==。它包含了Spring框架的核心组件,如BeanFactory和ApplicationContext等。
-
SpringContext模块:建立在SpringCore模块之上,提供了更广泛的应用程序上下文支持,如国际化、事件传播、资源加载、应用程序配置等。它还提供了许多企业级服务,如JNDI、EJB、JMS等。
-
SpringAOP模块:提供了面向切面编程的支持,可以将横切关注点(如日志记录、性能监视、事务管理等)从业务逻辑中分离出来。它使用代理模式实现,可以在不修改业务逻辑的情况下为应用程序添加新的功能。
-
SpringDAO模块:提供了对数据访问技术的支持,如JDBC、ORM、事务管理等。它提供了一组通用的异常层次结构,以及一些模板类,可以大大简化数据访问代码的编写。
-
SpringORM模块:提供了对ORM框架的支持,如Hibernate、JPA等。它可以将实体对象映射到数据库表中,从而使得开发人员可以使用面向对象的方式来操作数据库。
-
SpringWeb模块:提供了对Web应用程序的支持,如Spring MVC框架、WebSocket、REST等。它可以帮助开发人员快速构建Web应用程序,并提供了许多与Web相关的功能,如文件上传、表单处理、安全性等。
举一个例子,假设我们正在开发一个在线商城,我们可以使用Spring框架来实现这个应用程序。我们可以使用SpringCore模块来管理我们的对象,使用SpringContext模块来加载配置文件和资源,使用SpringAOP模块来处理安全和日志记录,使用SpringDAO模块来访问数据库,使用SpringORM模块来映射实体对象和数据库表,使用SpringWeb模块来处理Web请求和响应。这样,我们可以更快地开发出高质量的在线商城,并且更容易维护和扩展。
3.BeanFactory:
在SpringCore模块中,BeanFactory是一个接口,它是Spring框架中最基本的接口之一,用于==管理和维护Java对象(也称为Bean)==的创建、配置和生命周期。BeanFactory接口定义了一些基本的方法,包括获取Bean实例、销毁Bean实例等。
BeanFactory的主要作用是提供了一种机制,使得Java对象的创建和管理变得更加灵活和可配置。通过BeanFactory,我们可以将Java对象的创建和配置过程从应用程序中分离出来,从而实现了应用程序的松耦合和高内聚。
下面是一个简单的代码例子,演示了如何使用BeanFactory来创建和获取Java对象:
public class MainApp {
public static void main(String[] args) {
// 创建BeanFactory对象
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
// 获取HelloWorld对象
HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");
// 调用HelloWorld对象的方法
obj.getMessage();
}
}
在上面的代码中,我们首先创建了一个BeanFactory对象,然后通过调用getBean方法,获取了名为"helloWorld"的Bean实例。这个Bean实例是在配置文件applicationContext.xml中定义的,它是一个HelloWorld对象,其getMessage方法会输出一段字符串。
通过使用BeanFactory,我们可以将Java对象的创建和配置过程从应用程序中分离出来,从而实现了应用程序的松耦合和高内聚。同时,我们还可以通过修改配置文件,来改变Java对象的创建和配置过程,从而实现了应用程序的可配置性。
4.控制反转:
控制反转(Inversion of Control,IoC)是Spring框架的一个核心概念,指的是将对象的创建、组装和管理等控制权从应用程序代码中转移到框架或容器中,从而实现松耦合、可扩展和可维护的设计。
在传统的应用程序设计中,应用程序代码通常会负责创建和管理对象,这样会导致应用程序代码和对象之间的紧耦合,难以进行单元测试和代码重构。而控制反转则是将这些控制权转移到框架或容器中,让它们来负责对象的创建和管理,从而实现应用程序代码和对象之间的解耦和灵活性。
举一个简单的例子:
// OrderDAO类
public class OrderDAO {
// 数据访问实现
}
// OrderService类
public class OrderService {
private OrderDAO orderDAO; // 依赖注入的对象
public void setOrderDAO(OrderDAO orderDAO) { // Setter方法注入
this.orderDAO = orderDAO;
}
// 其他业务方法
}
// Spring配置文件
<bean id="orderService" class="com.example.OrderService"> <!-- 定义OrderService对象 -->
<property name="orderDAO" ref="orderDAO" /> <!-- 通过依赖注入方式使用OrderDAO对象 -->
上述的例子中,假设有一个订单服务类OrderService,它需要依赖一个订单数据访问对象OrderDAO来实现订单数据的持久化。在传统的设计中,OrderService需要自己创建和管理OrderDAO对象,这样会导致OrderService和OrderDAO之间的紧耦合,难以进行单元测试和代码重构。而在使用Spring框架的控制反转功能后,可以将OrderDAO的创建和管理交给Spring容器来完成,然后在OrderService中通过依赖注入的方式来使用OrderDAO对象,从而实现了松耦合和可测试的设计。
5.依赖注入:
依赖注入(Dependency Injection,DI)是一种实现控制反转(Inversion of Control,IoC)的方式,它是Spring框架的核心功能之一。简单来说,依赖注入就是将对象所依赖的其他对象注入到它的属性或构造函数中,而不是由对象自己创建或查找依赖的对象。
可参考控制反转的示例进行理解。
6.JavaBean与Spring的Bean:
JavaBean是指符合一定规范的Java类,它通常具有以下特征:
- 类是公共的
- 有一个无参构造方法
- 属性通过getter和setter方法进行访问
- 实现了Serializable接口
JavaBean的主要用途是封装数据,它可以将数据和行为封装在一个类中,从而实现了数据的安全性和可维护性。JavaBean通常用于在不同的层之间传递数据,
例如在MVC架构中,Controller层可以通过JavaBean来获取View层传递过来的数据,然后将数据传递给Model层进行处理。
Spring中的Bean是指在Spring容器中管理的Java对象,它们可以通过配置文件或注解来定义和创建。
Spring中的Bean与一般的JavaBean相比,有以下区别和联系:
区别:
- Spring中的Bean通常由Spring容器来创建和管理,而一般的JavaBean通常由程序员手动创建和管理。
- Spring中的Bean可以通过配置文件或注解来定义和创建,从而实现了更大程度的可配置性和灵活性。
- Spring中的Bean通常具有更多的功能和特性,例如依赖注入、面向切面编程、事务管理等。
联系:
- Spring中的Bean本质上也是JavaBean,它们都是Java类。
- Spring中的Bean也可以用于在不同的层之间传递数据,例如在MVC架构中,Controller层可以通过Spring中的Bean来获取View层传递过来的数据,然后将数据传递给Model层进行处理。
下面是一个简单的例子,演示了如何使用JavaBean和Spring中的Bean:
// 一般的JavaBean
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在上面的例子中,我们定义了一个一般的JavaBean User,它具有name和age两个属性,并且通过getter和setter方法进行访问。然后,我们定义了一个Spring中的Bean UserService,它依赖于UserDao对象,并且提供了addUser方法,用于添加用户。在Spring容器中配置UserService时,我们可以通过注入UserDao对象来实现依赖注入。这样,我们就可以在调用addUser方法时,直接使用userDao对象,而不需要在代码中显式地创建它。
7.Java的一般程序的生命周期与SpringBean的生命周期:
(1)Java程序的生命周期:
编写Java源代码,通过编译器将其编译成字节码文件。
将字节码文件加载到JVM中,并通过类加载器将其转换成Java类。
JVM将Java类转换成机器码,并执行程序。
程序执行完毕后,JVM将释放内存并结束程序。
(2)SpringBean的生命周期:
实例化:Spring容器通过反射机制创建一个Bean的实例。
属性赋值:Spring容器为Bean的属性赋值,可以通过XML配置或注解方式。
初始化:Spring容器调用Bean的初始化方法,可以通过XML配置或注解方式。
使用:Bean可以被其他对象引用,被调用。
销毁:Spring容器调用Bean的销毁方法,可以通过XML配置或注解方式。
(3)Java程序的生命周期与SpringBean的生命周期的区别和联系:
区别:
Java程序的生命周期是从编写代码到程序结束,而SpringBean的生命周期是从实例化到销毁。
Java程序的生命周期是由JVM控制,而SpringBean的生命周期是由Spring容器控制。
联系:
Java程序和SpringBean都有实例化、初始化、使用和销毁的过程。
Spring容器可以管理Java程序中的Bean,使得Java程序更加灵活和可扩展。
举例:
Java程序的生命周期:一个简单的Java程序,包括一个main方法和一些其他的方法。当我们运行这个程序时,JVM会先加载这个程序的字节码文件,然后执行main方法。当main方法执行完毕后,JVM会释放内存并结束程序。
SpringBean的生命周期:一个简单的SpringBean,包括一个属性和一个初始化方法。当Spring容器启动时,会通过反射机制创建这个Bean的实例,并为其属性赋值。然后调用Bean的初始化方法。当Bean被其他对象引用并使用时,就会执行相关的方法。当Spring容器关闭时,会调用Bean的销毁方法。
(4)JVM(Java虚拟机):
Java程序的运行环境,它是一个软件程序,负责将Java源代码编译成字节码=并执行。JVM提供了内存管理、垃圾回收、安全性和线程管理等基础服务,以及实现了Java语言的跨平台特性。
例如,当我们在开发Java程序时,将Java源代码编译成.class文件,然后在JVM上运行。JVM会将字节码转换成机器码并在计算机上执行。由于JVM的跨平台特性,我们可以在不同的操作系统上运行相同的Java程序。
下面是一个简单的Java程序示例:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
在命令行中,我们可以使用以下命令编译和运行该程序:
javac HelloWorld.java
java HelloWorld
在编译过程中,JVM会将Java源代码编译成字节码文件HelloWorld.class。在运行过程中,JVM会加载并执行该字节码文件,并输出字符串“Hello, World!”。
8.Java的一般容器与Spring中的容器:
Java的一般容器指的是Java集合框架中的容器,如List、Map、Set等。这些容器可以存储和管理Java对象,提供了方便的数据结构和算法。
Spring中的容器一般指的是Spring IOC容器,它是Spring框架的核心,用于管理Java对象的创建、配置、依赖注入和生命周期管理等。Spring容器可以帮助我们解耦和组织Java应用程序的各个模块,提高代码的可维护性和可扩展性。
举例:
Java的一般容器示例:
List<String> list = new ArrayList<>(); // 创建一个List容器
list.add("Java");
list.add("Spring");
list.add("MySQL");
System.out.println(list); // 输出:[Java, Spring, MySQL]
Map<String, String> map = new HashMap<>(); // 创建一个Map容器
map.put("name", "Tom");
map.put("age", "18");
map.put("gender", "male");
System.out.println(map); // 输出:{age=18, name=Tom, gender=male}
Spring中的容器示例:
1. 创建Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
2. 获取Bean对象
UserService userService = context.getBean("userService", UserService.class);
3. 使用Bean对象
User user = userService.getUserById(1);
System.out.println(user);
4. 销毁Spring容器
((ClassPathXmlApplicationContext) context).close();
在上述示例中,我们通过Spring容器创建了一个UserService对象,并使用它获取了一个User对象。在程序执行完毕后,我们通过close()方法销毁了Spring容器。这样,Spring容器就会自动管理UserService和User对象的生命周期,包括它们的创建、初始化、依赖注入和销毁等。
9.耦合和内聚:
耦合是指两个或多个模块之间的相互依赖关系。在软件开发中,模块之间的耦合性越高,就越难以维护和扩展。因此,我们通常希望模块之间的耦合性尽可能地低,从而实现模块之间的松耦合。
松耦合是指两个或多个模块之间的相互依赖关系较弱,模块之间的影响较小。在软件开发中,模块之间的松耦合能够提高代码的灵活性和可维护性,从而降低开发成本和维护成本。
Spring框架的设计目标之一就是实现松耦合的组件之间的依赖关系,以提高系统的可维护性和可扩展性。Spring通过依赖注入(Dependency Injection)和控制反转(Inversion of Control)等技术来实现松耦合。
举个例子,假设我们正在开发一个电子商务网站,我们需要实现用户注册和登录功能。如果我们的代码是紧耦合的,那么用户注册和登录的功能可能会写在同一个类中,这样就会导致代码难以维护和扩展。如果我们的代码是松耦合的,那么我们可以将用户注册和登录的功能分别写在不同的类中,从而使代码更加清晰和易于维护。
10.持久化:
持久化指的是将数据从内存中保存到外部存储介质(如硬盘、数据库等)中,并且能够在需要的时候将数据重新读取到内存中。持久化的目的是为了保证数据的长期存储和可靠性,以及方便数据的查询和处理。
举例来说,我们可以将一个Java对象保存到数据库中,这样即使程序结束或者重启,这个对象的数据也不会丢失,而且我们可以通过数据库查询语句来检索和处理这个对象的数据。
以下是一个Java对象持久化到MySQL数据库的示例:
- 定义一个Java对象
public class User {
private int id;
private String name;
private int age;
// 省略getter和setter方法
}
- 创建一个数据库表
CREATE TABLE user (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(20) NOT NULL,
age int(11) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=UTF-8;
- 使用JDBC将Java对象保存到数据库中
public void saveUser(User user) {
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConnection();
String sql = "INSERT INTO user (name, age) VALUES (?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, user.getName());
ps.setInt(2, user.getAge());
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(conn, ps, null);
}
}
- 使用JDBC从数据库中读取Java对象
public User getUserById(int id) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
User user = null;
try {
conn = getConnection();
String sql = "SELECT * FROM user WHERE id = ?";
ps = conn.prepareStatement(sql);
ps.setInt(1, id);
rs = ps.executeQuery();
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(conn, ps, rs);
}
return user;
}
在上述示例中,我们通过JDBC将Java对象User保存到MySQL数据库中,并且能够从数据库中读取User对象的数据。这样,就实现了Java对象的持久化。
二、第一个基于Spring的程序:
(1)创建一个Java Project
(2)新建一个lib
文件夹:
(3)配置环境:
将jar包放到lib下后,Built Path
(4)配置文件:
在src下new一个xml文件
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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 声明schema文件路径 -->
<bean name="c" class="com.how2java.pojo.Category"> <!-- 定义一个名为"c"的bean,类型为Category -->
<property name="name" value="category 1" /> <!-- 设置属性name的值为"category 1" -->
</bean>
</beans>
property选择要注入的属性,value确定值。
(5)实体类:
在scr的包com.how2java.pojo下new一个class
Category.java:
package com.how2java.pojo;
public class Category {
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private int id;
private String name;
}
(6)测试类:
在scr的包com.how2java.test下new一个class
TestSpring.java:
package com.how2java.test; // 包名
import org.springframework.context.ApplicationContext; // 导入类 ApplicationContext
import org.springframework.context.support.ClassPathXmlApplicationContext; // 导入类 ClassPathXmlApplicationContext
import com.how2java.pojo.Category; // 导入类 Category
public class TestSpring { // 定义一个类 TestSpring
public static void main(String[] args) { // 定义一个公有静态方法 main()
ApplicationContext context = new ClassPathXmlApplicationContext( // 创建一个 ApplicationContext 对象 context
new String[] { "applicationContext.xml" }); // 从 applicationContext.xml 配置文件中读取配置信息
Category c = (Category) context.getBean("c"); // 从容器中获取 id 为 "c" 的 bean,转换为 Category 类型的对象 c
System.out.println(c.getName()); // 输出 c 对象的 name 属性值
}
}