Spring- 基本概述

本文介绍了Spring框架的基本概念,包括其起源、优点和框架体系结构。Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器,核心组件是BeanFactory。文章还讨论了传统JDBC实现的缺点,并引入工厂模式进行解耦,解释了控制反转(IOC)的概念。
摘要由CSDN通过智能技术生成

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)

传统获取对象的方式

通过工厂模式获取对象的方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值