一、Spring框架
1.1.原生web开发中存在哪些问题?
传统Web开发存在硬编码所造成的过度程序耦合(例如:Service中作为属性Dao对象)。
部分Java EE API较为复杂,使用效率低(例如:JDBC开发步骤)。
侵入性强,移植性差(例如:DAO实现的更换,从Connection到SqlSession)。
1.2.什么是Spring
Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器(框架)。
Spring是一个项目管理框架,同时也是一套Java EE解决方案。
Spring是众多优秀设计模式的组合(工厂、单例、代理、适配器、包装器、观察者、模板、策略)。
Spring并未替代现有框架产品,而是将众多框架进行有机整合,简化企业级开发,俗称"胶水框架"。
1.3.Spring架构组成
Spring架构由诸多模块组成,可分类为
GroupId | ArtifactId | 说明 |
---|---|---|
org.springframework | spring-beans | Beans 支持,包含 Groovy |
org.springframework | spring-aop | 基于代理的AOP支持 |
org.springframework | spring-aspects | 基于AspectJ 的切面 |
org.springframework | spring-context | 应用上下文运行时,包括调度和远程抽象 |
org.springframework | spring-context-support | 支持将常见的第三方类库集成到 Spring 应用上下文 |
org.springframework | spring-core | 其他模块所依赖的核心模块 |
org.springframework | spring-expression | Spring 表达式语言,SpEL |
org.springframework | spring-instrument | JVM 引导的仪表(监测器)代理 |
org.springframework | spring-instrument-tomcat | Tomcat 的仪表(监测器)代理 |
org.springframework | spring-jdbc | 支持包括数据源设置和 JDBC 访问支持 |
org.springframework | spring-jms | 支持包括发送/接收JMS消息的助手类 |
org.springframework | spring-messaging | 对消息架构和协议的支持 |
org.springframework | spring-orm | 对象/关系映射,包括对 JPA 和 Hibernate 的支持 |
org.springframework | spring-oxm | 对象/XML 映射(Object/XML Mapping,OXM) |
org.springframework | spring-test | 单元测试和集成测试支持组件 |
org.springframework | spring-tx | 事务基础组件,包括对 DAO 的支持及 JCA 的集成 |
org.springframework | spring-web | web支持包,包括客户端及web远程调用 |
org.springframework | spring-webmvc | REST web 服务及 web 应用的 MVC 实现 |
org.springframework | spring-webmvc-portlet | 用于 Portlet 环境的MVC实现 |
org.springframework | spring-websocket | WebSocket 和 SockJS 实现,包括对 STOMP 的支持 |
org.springframework | spring-jcl | Jakarta Commons Logging 日志系统 |
二、Spring环境搭建
2.1.构建maven项目
2.1.1新建项目
使用IDEA打开已创建的文件夹目录 |
![]() |
2.1.2选择Maven依赖
选择Maven项目 |
![]() |
2.1.3GAV坐标
GAV坐标 |
![]() |
2.2pom.xml中引入Spring常用依赖
<dependencies>
<!--spring-context依赖关联了其他核心依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.14.RELEASE</version>
</dependency>
<!--单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<!--set、get、toString-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
</dependencies>
2.3创建Spring配置文件
位置: resources下
格式: xml
名称: 一般叫做applicationContext.xml、beans.xml、spring-context.xml、app.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">
</beans>
三、Spring工厂编码
定义Bean类型。
public class MyClass{
public void show(){
System.out.println("HelloWorld");
}
}
applicationContext.xml中的< beans >内部配置bean标签。
- id:唯一标识
- class:需要被创建的目标对象全限定名
<!-- 配置实例(id:“唯一标识” class="需要被创建的目标对象全限定名")-->
<bean id="mc" class="com.qf.spring.part1.factory.MyClass" />
调用Spring工厂API(ApplicationContext接口)
- 程序中的对象都交由Spring的ApplicationContext工厂进行创建。
public class TestFactory{
/**
* 程序中的对象都交由Spring的ApplicationContext工厂进行创建。
*/
public static void main(String[] args){
//1. 读取配置文件中所需创建的bean对象,并获得工厂对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 通过id获取bean对象
MyClass myClass = (MyClass) context .getBean("mc");
//3. 使用对象
myClass .show();
}
}
四、依赖与配置文件详解
Spring框架包含多个模块,每个模块各司其职,可结合需求引入相关依赖Jar包实现功能。
4.1 Spring依赖关系
Spring常用功能的Jar包依赖关系 |
![]() |
4.2 schema
配置文件中的顶级标签中包含了语义化标签的相关信息
xmlns:语义化标签所在的命名空间。
xmlns:xsi:XMLSchema-instance 标签遵循Schema标签标准。
xsi:schemaLocation:xsd文件位置,用以描述标签语义、属性、取值范围等。
五、IOC(Inversion of Control)控制反转
IOC控制反转,负责创建对象,管理对象,依赖注入的方式将创建的对象和对象之间的维护交由Spring管理。
Spring:Spring容器使用工厂模式创建对象,不用自己创建,直接调用即可。
- 反转了依赖关系的满足方式,由之前的自己创建依赖对象,变为由工厂推送。(变主动为被动,即反转)
5.1 项目中强耦合问题
public interface UserDao {
void findUserById();
}
public class UserDaoImpl implements UserDao {
@Override
public void findUserById() {
System.out.println("UserDaoImpl执行了");
}
}
public interface UserService {
void findUserById();
}
public class UserServiceImpl implements UserService {
// 强耦合了UserDAOImp!,使得UserServiceImpl变得不稳健!
private UserDao userDao= new UserDaoImpl();
@Override
public void queryUser() {
userDao.findUserById();
System.out.println("UserServiceImpl执行了");
}
....
}
5.2 解决方案
public interface UserService {
void findUserById();
}
// 不引用任何一个具体的组件(实现类),在需要其他组件的位置预留存取值入口(set/get)
public class UserServiceImpl implements UserService {
// 不再耦合任何Dao实现!消除不稳健因素!
private UserDao userDao;
// 为userDao定义set/get方法,允许userDao属性接受spring赋值
// Getters And Setters
@Override
public void findUserById() {
System.out.println("UserServiceImpl.findUserById()执行" );
}
....
}
5.3 applicaionContext.xml配置
- 一个bean标签代表一个类,会创建该类对象
- class:需要被创建的目标对象全限定名
- id:创建完成后的对象名
<?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">
<!-- spring配置文件applicationContext.xml相当于是
一个容器,在这里配置整个项目中所需要的对象
-->
<!-- 一个bean标签代表一个类,会创建该类对象
class 是要交给Spring创建对象的类路径
id 是创建完成后的对象名
-->
<bean id="userDao" class="com.ymk.dao.UserDaoImpl"></bean>
<!--UserDaoImpl组件-->
<bean id="userService" class="com.ymk.service.UserServiceImpl">
<!--由spring给userDao属性赋值
1)属性要有set方法
2)属性值是另一个类对象,所以需要使用ref引用另一个类的对象id-->
<property name="userDao" ref="userDao"/>
</bean>
</beans>
此时,如果需要更换其他UserDao实现类,则UserServiceImpl不用任何改动!
则此时的UserServiceImpl组件变得更加稳健!
5.4测试
public class TsetIOC {
@Test
public void test(){
String path = "applicationContext.xml";
// 根据配置文件创建出spring容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(path);
// 从容器中取出对象(根据对象名获得对象,配置文件中bean的id)
UserService userService = (UserService) context.getBean("userService");
userService.findUserById();
}
}