1.1 基本概念
1.1.1 基本简介
- Spring : 春天 —>给软件行业带来了春天
- 2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
- 2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。
- Spring理念 : 使现有技术更加实用 . 本身就是一个大杂烩 , 整合现有的框架技术。
官网 : http://spring.io/
官方下载地址 : https://repo.spring.io/libs-release-local/org/springframework/spring/
GitHub : https://github.com/spring-projects
1.1.2 优点和总结
优点
- Spring是一个开源免费的框架 , 容器 。
- Spring是一个轻量级的框架 , 非侵入式的 。
- 控制反转 IoC , 面向切面 Aop。对事物的支持 , 对框架的支持
总结
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)
1.1.3 框架体系结构
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式 。
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
核心容器
- 核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory ,它是工厂模式的实现。
- BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
Spring 上下文
- Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。
Spring AOP
- 通过配置管理特性Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring框架中。可以很容易地使 Spring 框架管理任何支持 AOP的对象。
- Spring AOP 模块为基于Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP不用依赖组件,就可以将声明性事务管理集成到应用程序中。
Spring DAO
- JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。
- 异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量。
- Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
Spring ORM
- Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。
- 所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
Spring Web 模块
- Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。
- Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
Spring MVC 框架:
- MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。
- 通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText和 POI。
1.2 JDBC 实现(传统方式)
1.2.1 SQL数据表
-- 创建数据库
create database spring;
-- 显示数据库
show databases;
-- 使用数据库
use spring;
-- 创建客户表
CREATE TABLE `cst_customer` (
`cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',
`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',
`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',
`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',
`cust_address` varchar(128) DEFAULT NULL COMMENT '客户联系地址',
`cust_phone` varchar(64) DEFAULT NULL COMMENT '客户联系电话',
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 添加客户数据
INSERT INTO `cst_customer` VALUES ('1', '美团外卖','网络营销', '互联网', '普通客户','北京市海淀区北四环西路9号','7758258');
INSERT INTO `cst_customer` VALUES ('2', '360公司','网络安全', '互联网', '普通客户','北京市朝阳区酒仙桥路6号院','0208888887');
INSERT INTO `cst_customer` VALUES ('3', '百度','网络搜索', '互联网', '普通客户','北京朝阳区','389056');
INSERT INTO `cst_customer` VALUES ('4', '小米','手机制造', '互联网+', 'VIP','武汉光谷','2267890');
INSERT INTO `cst_customer` VALUES ('5', '腾讯','网络广告', '互联网', 'VIP','深圳市南山区','123456');
INSERT INTO `cst_customer` VALUES ('6', '华为','电视广告', '高新科技制造业', 'VIP','深圳龙岗','033567');
-- 查询数据库
select * from cst_customer;
1.2.2 项目目录
导入父依赖(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.guardwhy</groupId>
<artifactId>Spring</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<!--模块-->
<modules>
<module>01_spring_jdbc</module>
</modules>
<properties>
<!-- spring版本 -->
<spring.version>5.2.9.RELEASE</spring.version>
<!-- mysql版本 -->
<mysql.version>5.1.30</mysql.version>
</properties>
<dependencies>
<!--spring 版本-->
<dependency>
<groupId>org.springframework </groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!--测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
<!-- mysql数据库依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>
</project>
倒入子依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>Spring</artifactId>
<groupId>cn.guardwhy</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>01_spring_jdbc</artifactId>
</project>
1.2.3 测试代码
package cn.guardwhy.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class JdbcDemo01 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement psmt = null;
ResultSet rs = null;
try {
// 1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.创建数据库链接对象
connection = DriverManager.getConnection("jdbc:mysql:///spring", "root", "root");
// 3.定义sql语句
String sql = "select * from cst_customer";
// 4.创建Statement语句对象
psmt = connection.prepareStatement(sql);
// 5.执行操作
rs = psmt.executeQuery();
// 6.处理结果集
while (rs.next()){
System.out.println("客户Id:" + rs.getInt("cust_id") + ", 客户名称:" + rs.getString("cust_name"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 7.释放资源
try {
if(rs != null) rs.close();
if(psmt != null) psmt.close();
if(connection != null) connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结论
代码的耦合度太高了,不利于后期维护!!!!
1.3 工厂模式解耦
1.3.1 项目目录
1.3.2 代码实现
配置文件(bean.properties)
CUSTOMERDAO=cn.guardwhy.dao.impl.CustomerDaoImpl
CUSTOMERSERVICE=cn.guardwhy.service.impl.CustomerServiceImpl
BeanFactory工厂类
package cn.guardwhy.factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 工厂类实现
*/
public class BeanFactory {
// 1.声明一个私有的工厂类对象引用
private static BeanFactory beanFactory;
// 2.将构造方法私有化
private BeanFactory(){
}
// 3.通过静态代码块初始化
// 定义Properties
private static Properties prop;
static {
// 创建工厂类对象
beanFactory = new BeanFactory();
// 创建prop对象,加载属性配置文件
prop = new Properties();
InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
try {
prop.load(inputStream);
} catch (IOException e) {
e.printStackTrace();
System.out.println("加载属性资源文件,发生异常:" + e.getMessage());
}
}
// 4.提供一个公有的、静态的方法,获取工厂类对象引用
public static BeanFactory getBeanFactory(){
return beanFactory;
}
/**
* 1.通过配置文件,将要创建的目标对象的类型信息,进行配置
* 2.在工厂类中加载配置文件,通过反射技术实现运行时加载,并创建目标对象
*/
public Object getBean(String beanName){
// 目标对象
Object result = null;
// 获取类路径
String className = prop.getProperty(beanName);
// 反射技术创建对象
try {
result = Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
System.out.println("运行时创建对象,发生异常:" + className);
}
return result;
}
}
持久层(Dao层)
dao层接口
package cn.guardwhy.dao;
/**
* 客户dao接口
*/
public interface CustomerDao {
/**
* 保存客户操作
*/
void saveCustomer();
}
dao实现类
package cn.guardwhy.dao.impl;
import cn.guardwhy.dao.CustomerDao;
/**
* 客户dao实现类
*/
public class CustomerDaoImpl implements CustomerDao {
@Override
public void saveCustomer() {
System.out.println("保存客户操作");
}
}
业务层(Service)
service接口
package cn.guardwhy.service;
/**
* 客户service接口
*/
public interface CustomerService {
/**
* 保存客户操作
*/
void saveCustomer();
}
service实现类
package cn.guardwhy.service.impl;
import cn.guardwhy.dao.CustomerDao;
import cn.guardwhy.factory.BeanFactory;
import cn.guardwhy.service.CustomerService;
/**
* 客户service实现类
*/
public class CustomerServiceImpl implements CustomerService {
// 从工厂类获取客户dao对象
private CustomerDao customerDao = (CustomerDao) BeanFactory.getBeanFactory().getBean("CUSTOMERDAO");
/**
* 保存客户操作
*/
@Override
public void saveCustomer() {
customerDao.saveCustomer();
}
}
表现层(Controller)
Controller
package cn.guardwhy.controller;
import cn.guardwhy.factory.BeanFactory;
import cn.guardwhy.service.CustomerService;
public class CustomerController {
public static void main(String[] args) {
// 从工厂类获取客户端service对象
CustomerService customerService = (CustomerService) BeanFactory.getBeanFactory().getBean("CUSTOMERSERVICE");
// 保存客户操作
customerService.saveCustomer();
}
}
执行结果
1.3.3 工厂模式解耦
工厂就是负责创建对象,并且把对象放到容器中。在实际使用的时候,帮助我们从容器获取指定的对象。此时获取对象的方式发生了改变。
原来获取对象时,都是采用new的方式,是主动获取。现在我们获取对象时,找工厂要,由工厂创建并且提供给,是被动接收。
结论:这种获取对象方式的转变(由原来主动获取,到现在被动接收),我们称它为控制反转。控制反转,即IOC(Inversion Of Control)。
传统获取对象的方式
通过工厂模式获取对象的方式