前言

为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。
(博客的参考源码以及可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)


发现宝藏

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。

一、Spring是什么?

1.概述

  • Spring Framework 是一个功能强大的 Java 应用程序框架,旨在提供高效且可扩展的开发环境。
  • 它结合了轻量级的容器(IOC)和 依赖注入(DI) 功能,提供了一种使用 POJO 进行容器配置和面向切面的编程的简单方法,以及一组用于 AOP(切面编程) 的模块。
  • Spring 框架还支持各种移动应用开发技术,如 Android 和 iOS。此外,它还提供了对事务管理、对象/关系映射、JavaBeans、JDBC、JMS 和其他技术的支持,从而确保高效开发。

2.了解spring家族

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.spring系统概述

Spring 有可能成为所有企业应用程序的一站式服务点,然而,Spring 是模块化的,允许你挑选和选择适用于你的模块,不必要把剩余部分也引入。下面的部分对在 Spring 框架中所有可用的模块给出了详细的介绍。

Spring 框架提供约 20 个模块,可以根据应用程序的要求来使用。

在这里插入图片描述

  1. 核心容器(Core Container)

核心容器由 spring-core,spring-beans,spring-context,spring-context-support和spring-expression(SpEL,Spring 表达式语言,Spring Expression Language)等模块组成,它们的细节如下:

spring-core 模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。

spring-beans 模块提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。

context 模块建立在由 core和 beans 模块的基础上建立起来的,它以一种类似于 JNDI 注册的方式访问对象。Context 模块继承自 Bean 模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过 Servelet 容器)等功能。Context 模块也支持 Java EE 的功能,比如 EJB、JMX 和远程调用等。ApplicationContext 接口是 Context 模块的焦点。spring-context-support 提供了对第三方集成到 Spring 上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。

spring-expression 模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是 JSP2.1 规范中定义的统一表达式语言的扩展,支持 set 和 get 属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从 Spring IoC 容器检索对象,还支持列表的投影、选择以及聚合等。
  1. 数据访问/集成(Data Access/Integration)
    数据访问/集成层包括 JDBC,ORM,OXM,JMS 和事务处理模块,它们的细节如下:

(注:JDBC=Java Data Base Connectivity,ORM=Object Relational Mapping,OXM=Object XML Mapping,JMS=Java Message Service)

JDBC 模块提供了 JDBC 抽象层,它消除了冗长的 JDBC 编码和对数据库供应商特定错误代码的解析。

ORM 模块提供了对流行的对象关系映射 API 的集成,包括 JPA、JDO 和 Hibernate 等。通过此模块可以让这些 ORM 框架和 spring的其它功能整合,比如前面提及的事务管理。

OXM 模块提供了对 OXM 实现的支持,比如 JAXB、Castor、XML Beans、JiBX、XStream 等。

JMS 模块包含生产(produce)和消费(consume)消息的功能。从 Spring 4.1 开始,集成了 spring-messaging 模块。

事务模块为实现特殊接口类及所有的 POJO 支持编程式和声明式事务管理。(注:编程式事务需要自己写 beginTransaction()、commit()、rollback() 等事务管理方法,声明式事务是通过注解或配置由 spring 自动处理,编程式事务粒度更细)
  1. Web

Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下:

Web 模块提供面向 web 的基本功能和面向 web 的应用上下文,比如多部分(multipart)文件上传功能、使用 Servlet 监听器初始化 IoC 容器等。它还包括 HTTP 客户端以及 Spring 远程调用中与 web 相关的部分。

Web-MVC 模块为 web 应用提供了模型视图控制(MVC)和 REST Web服务的实现。Spring 的 MVC 框架可以使领域模型代码和 web 表单完全地分离,且可以与 Spring 框架的其它所有功能进行集成。

Web-Socket 模块为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。

Web-Portlet 模块提供了用于 Portlet 环境的 MVC 实现,并反映了 spring-webmvc 模块的功能。 
  1. Test模块

Test 模块:Spring 支持 Junit 和 TestNG 测试框架,而且还额外提供了一些基于 Spring 的测试功能,比如在测试 Web 框架时,模拟 Http 请求的功能。

  1. 其他

还有其他一些重要的模块,像 AOP,Aspects,Instrumentation,Web 和测试模块,它们的细节如下:

AOP 模块提供了面向方面(切面)的编程实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,从而使实现功能的代码彻底的解耦出来。使用源码级的元数据,可以用类似于.Net属性的方式合并行为信息到代码中。

Aspects 模块提供了与 AspectJ 的集成,这是一个功能强大且成熟的面向切面编程(AOP)框架。

Instrumentation 模块在一定的应用服务器中提供了类 instrumentation 的支持和类加载器的实现。

Messaging 模块为 STOMP 提供了支持作为在应用程序中 WebSocket 子协议的使用。它也支持一个注解编程模型,它是为了选路和处理来自 WebSocket 客户端的 STOMP 信息。

测试模块支持对具有 JUnit 或 TestNG 框架的 Spring 组件的测试

4.spring优点

  • 方便解耦,简化开发

Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理

  • 方便集成各种优秀框架

Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis 等)的直接支持

  • 降低 Java EE API 的使用难度

Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些 API 应用的难度大大降低

  • 方便程序的测试

Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序

  • AOP 编程的支持

Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能

  • 声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无须手动编程。

5.spring学习路线

在这里插入图片描述

二、入门spring

1.核心概念

  1. 依赖注入(DI
  • Spring 最认同的技术是控制反转的依赖注入(DI)模式。控制反转(IoC)是一个通用的概念,它可以用许多不同的方式去表达,依赖注入仅仅是控制反转的一个具体的例子

  • 当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能的独立于其他的 Java 类来增加这些类可重用可能性,当进行单元测试时,可以使它们独立于其他类进行测试。依赖注入(或者有时被称为配线)有助于将这些类粘合在一起,并且在同一时间让它们保持独立。

  • 到底什么是依赖注入?让我们将这两个词分开来看一看。这里将依赖关系部分转化为两个类之间的关联。例如,类 A 依赖于类 B。现在,让我们看一看第二部分,注入。所有这一切都意味着类 B 将通过 IoC 被注入到类 A 中。

  • 依赖注入可以以向构造函数传递参数的方式发生,或者通过使用 setter 方法 post-construction。由于依赖注入是 Spring 框架的核心部分,所以我将在一个单独的章节中利用很好的例子去解释这一概念。

2.面向切面的程序设计(AOP):

  • Spring 框架的一个关键组件是面向切面的程序设计(AOP)框架。一个程序中跨越多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑。有各种各样常见的很好的关于方面的例子,比如日志记录、声明性事务、安全性,和缓存等等。

  • 在 OOP 中模块化的关键单元是类,而在 AOP 中模块化的关键单元是方面。AOP 帮助你将横切关注点从它们所影响的对象中分离出来,然而依赖注入帮助你将你的应用程序对象从彼此中分离出来。

  • Spring 框架的 AOP 模块提供了面向方面的程序设计实现,可以定义诸如方法拦截器和切入点等,从而使实现功能的代码彻底的解耦出来。使用源码级的元数据,可以用类似于 .Net 属性的方式合并行为信息到代码中。我将在一个独立的章节中讨论更多关于 Spring AOP 的概念。

  1. Spring IoC 容器
  • Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans

  • 通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。配置元数据可以通过 XML,Java 注释或 Java 代码来表示。下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序

在这里插入图片描述

  • IOC 容器具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中BeanFactory是IOC容器的实际代表者。

  • Spring 提供了以下两种不同类型的容器。

序号容器 & 描述
1Spring BeanFactory 容器 :它是最简单的容器,给 DI 提供了基本的支持,它用 org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory 或者相关的接口,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。
2Spring ApplicationContext 容器 :该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。

ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常不建议使用BeanFactory。BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。

  1. Spring Bean 定义
  • 被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的,例如,已经在先前章节看到的,在 XML 的表单中的 定义。

  • bean 定义包含称为配置元数据的信息,下述容器也需要知道配置元数据:

    • 如何创建一个 bean

    • bean 的生命周期的详细信息

    • bean 的依赖关系

上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。

属性描述
class这个属性是强制性的,并且指定用来创建 bean 的 bean 类。
name这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。
scope这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。
constructor-arg它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
properties它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
autowiring mode它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
lazy-initialization mode延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。
initialization 方法在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。
destruction 方法当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。
  • Bean 与 Spring 容器的关系

在这里插入图片描述## 5.spring三层架构

A 表现层   web层    MVC是表现层的一个设计模型 

B 业务层  service层

C 持久层  dao层

2.IOC入门案例

  1. 入门案例思路分析

在这里插入图片描述

  1. 创建maven模块

在这里插入图片描述

  1. 编写接口和Dao实现类(此时无spring环境,纯JAVA开发)
  • 模块代码结构
    在这里插入图片描述

  • BookDao

public interface BookDao {
    public void save();
}

  • BookDaoImpl
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}

  • BookService
public interface BookService {
    public void save();
}
  • BookServiceImpl
public class BookServiceImpl implements BookService {
    private BookDao bookDao = new BookDaoImpl();

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}
  • Main
public class Main {
    public static void main(String[] args) {
        BookService bookService = new BookServiceImpl();
        bookService.save();
    }
}
  • Main类运行结果

在这里插入图片描述

  1. 示例代码解析
  • 首先写了两个数据层接口 BookDao 和 BookService,两个接口中都定义了save()方法
  • 然后写了两个数据层接口的实现类 BookDaoImpl 和 BookServiceImpl,分别实现了save() 方法,方法里都要一条输出语句,但是两个实现类save方法打印的内容不同
  • 其中 BookServiceImpl 类中还通过new创建对象的方式调用了 BookDaoImpl的save方法
  • 最后在Main类中通过new创建对象的方式调用了BookServiceImpl的save方法将两个save()方法中的语句打印了出来
  1. 在pom.xml中导入spring坐标spring-context
 <dependencies>
        <!--spring坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.21.RELEASE</version>
        </dependency>
    </dependencies>

  1. 创建spring核心配置文件applicationContext.xml

resources 目录右键 --> new --> XML Configuration File --> Spring Config(导入spring坐标后才有对应选项)

在这里插入图片描述

  1. 配置Bean(如下)
<?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">

       <!--1.导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->

       <!--2.配置bean-->
       <!--bean标签标示配置bean
       id属性标示给bean起名字
       class属性表示给bean定义类型-->
       <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>

       <bean id="bookService" class="org.example.service.impl.BookServiceImpl"/>
               
</beans>
  1. 在org.example下新建一个类Main2
public class Main2 {
    public static void main(String[] args) {
        //3.获取IoC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //4.获取bean(根据bean配置id获取)
        //左边是对象,右边是接口,所以要强转类型
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}
  • 程序运行结果(通过spring创建对象而不是通过new创建对象)

在这里插入图片描述

  1. 总结 :spring程序的开发步骤

在这里插入图片描述

3.DI入门案例

  1. 删除BookServiceImpl类中通过new方式创建对象的代码,并提供对应的setter方法
package org.example.service.impl;

import org.example.dao.BookDao;
import org.example.service.BookService;

public class BookServiceImpl implements BookService {
    //5.删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;
//    private BookDao bookDao = new BookDaoImpl();

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    //    6.提供对应的set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

  1. 在全局配置文件applicationContext.xml文件中将BookDao注入到BookService中
<?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">

       <!--1.导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->

       <!--2.配置bean-->
       <!--bean标签标示配置bean
       id属性标示给bean起名字
       class属性表示给bean定义类型-->
       <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>

       <bean id="bookService" class="org.example.service.impl.BookServiceImpl">
       <!--7.配置server与dao的关系-->
       <!--property标签表示配置当前bean的属性
       name属性表示配置哪一个具体的属性
       ref属性表示参照哪一个bean-->
       <property name="bookDao" ref="bookDao"/>
       </bean>

</beans>

  1. 运行结果

在这里插入图片描述

  1. 注意事项

name 的值是类的属性值,ref的值是id值

在这里插入图片描述

4.bean的配置

  1. bean的基础配置

在这里插入图片描述

  1. bean的别名设置

在这里插入图片描述

  1. 控制bean的作用范围

在这里插入图片描述

5.IOC容器相关

  1. 创建容器

在这里插入图片描述

  1. 获取bean的方式

在这里插入图片描述

  1. 容器类层次结构

(BeanFactory接口创建完毕后,所有的bean均为延迟加载)

在这里插入图片描述

三、数据源对象管理

1. 数据源对象管理入门案例

1. 导入数据源坐标(以druid数据源为例)

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

2. 在核心配置文件中配置管理数据源对象(由于第三方技术已经写好,注入方式以及具体属性名需要查

<bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

3. 创建编写模拟配置类App及其运行结果

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource);
        
    }
}

在这里插入图片描述

2. 加载properties配置文件

1. 在resources目录下创建jdbc.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root

2. 在核心配置类中开启context命名空间

在这里插入图片描述

3. 使用context空间加载properties文件

<?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.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            ">

<!--    1.开启context命名空间-->
<!--    2.使用context空间加载properties文件-->
<!--    属性占位符,location:加载的文件-->
    <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
<!--    3.使用属性占位符${}读取properties文件中的属性-->
<!--    说明:idea自动识别${}加载的属性值,需要手工点击才可以查阅原始书写格式-->
    <bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl">
        <property name="name" value="${jdbc.driver}"/>
    </bean>

</beans>

4. 将绑定好的properties属性注入到bookdao中,通过bookdao中的save方法输出

public interface BookDao {
    public void save();
}

public class BookDaoImpl implements BookDao {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void save() {
        System.out.println("book dao save ..." + name);
    }
}

5. 模拟测试类及输出结果

在这里插入图片描述
6. 小结和拓展

在这里插入图片描述
在这里插入图片描述

总结

欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐