IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java从入门到精通二十六(Spring框架) -> 正文阅读

[Java知识库]java从入门到精通二十六(Spring框架)

Spring 架构

在这里插入图片描述

按照这个图的说明(4版本架构图)

核心层
Core Container:核心容器,这个模块是Spring最核心的模块,其他的都需要依赖该模块
AOP层
AOP:面向切面编程,它依赖核心层容器,目的是在不改变原有代码的前提下对其进行功能增强
数据层
Data Access:数据访问,Spring全家桶中有对数据访问的具体实现技术
Data Integration:数据集成,Spring支持整合其他的数据层解决方案,比如Mybatis
Transactions:事务,Spring中事务管理是Spring AOP的一个具体实现
web层
在SpringMVC框架体现
Test层
那就是测试,集合Junit完成单元测试和集成测试。

一般我们都说这个轻量级框架是为企业级开发而生的,开源,并且几乎可以支持主流的所有框架,简化了代码操作。所提供的的两个核心就是就是IOC(控制反转),AOP(面向切面编程)。我们在这里的介绍首先先知道一下。

首先还有就是这里我们主要还是先说明的就是Spring是一个大的家族,并不是说Spring就是单指一个Spring技术。
在这里插入图片描述
以后我们还需要注意
在这里插入图片描述

目前本文介绍的还是==Spring Framework这边。因为这个是比较核心的。是基础。
SpringCloud:这个是用来做分布式之微服务架构的相关开发。
SpringCloud:这个是用来做分布式之微服务架构的相关开发

按照黑马给出的条例的这个框架的学习路线图

在这里插入图片描述
那么我们的起点就从核心容器这边开始,包括控制反转(IOC),依赖注入(DI),Bean(其实是对象)等这些开始。
我们大体了解到这些。
我们应该从分析项目存在的一些问题引入。

分析一个项目存在的问题

现在我们先给出几部分简单的代码

层次是这样的。

在这里插入图片描述

在dao层,接口

package jgdabc.dao;

public interface BookDao {
    public void save();
}

接口实现

package jgdabc.dao.impl;

import jgdabc.dao.BookDao;

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

service层
接口

package jgdabc.service;

public interface BookService {
    public void save();
}

接口实现

package jgdabc.service.impl;

import jgdabc.dao.BookDao;
import jgdabc.dao.impl.BookDaoImpl;
import jgdabc.service.BookService;

public class BookServiceImpl implements BookService {

        private BookDao bookDao = new BookDaoImpl();
        public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

}

我们看的这个service调用了dao层的方法。存在的问题就是业务层需要调用数据层方法,然后又我们看到了这里也new了数据层的接口实现类。
但是呢如果数据层得实现类需要做出优化,发生变化,那么业务层是一定要改变的。起码得new出对象,但是这样的话其实在将来的项目中,我们需要重新编译和重新部署。这样如果项目庞大的话,将带来一些代价成本。

这里按照黑马的教程里面讲到一个词叫做耦合度。代码飞耦合度。
代码的耦合度,是指代码中的单元代码的紧密程度,其中一个单元代码的更改对其它单元代码的影响力与作用

也就是说。如果我们代码之前存在太多的相互关联,当一部分代码需要优化或者改进的时候,我们其他的代码段也面临着改动。如果项目庞大的话,这将付出巨大的代价。

所以我们先从对象的问题上尝试解决。
如何在业务层中不在new出数据层的实现对象呢?这样就降低了耦合度。而这个问题,Spring给出了我们的解决方案。

IOC控制反转(IOC)

首先我们要明白什么是控制反转。
使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转。

在上诉程序的具体提现就是我们的service实现类对数据层的实现方法对象的创建由外部提供。

业务层要用数据层的类对象,以前是自己new 的现在自己不new了,交给别人[外部] 来创建对象别人[外部] 就反转控制了数据层对象的创建权这种思想就是控制反转

Spring和IOC之间的关系是什么呢?
Spring技术对IOC思想进行了实现
Spring提供了一个容器,称为IOC容器,用来充当IOC思想中的"外部"
IOC思想中的别人[外部] 指的就是Spring的IOC容器
IOC容器的作用以及内部存放的是什么?
IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象被创建或被管理的对象在IOC容器中统称为Bean
IOC容器中放的就是一个个的Bean对象
当IOC容器中创建好service和dao对象后,程序能正确执行么?
不行,因为service运行需要依赖dao对象
IOC容器中虽然有service和dao对象
但是service对象和dao对象没有任何关系
需要把dao对象交给service,也就是说要绑定service和dao对象之间的关系
像这种在容器中建立对象与对象之间的绑定关系就要用到DI:

依赖注入(DI)

(1) 什么是依赖注入呢?
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入业务层要用数据层的类对象,以前是自己new 的现在自己不new了,靠别人[外部其实指的就是IOC容器] 来给注入进来,这种思想就是依赖注入
在这里插入图片描述
(2) IOC容器中哪些bean之间要建立依赖关系呢?
这个需要程序员根据业务需求提前建立好关系,如业务层需要依赖数据层,service就要和dao建立依赖关系
介绍完Spring的IOC和DI的概念后,我们会发现这两个概念的最终目标就是:充分解耦,具体实现靠: 使用IOC容器管理bean(IOC)
在IOC容器内将有依赖关系的bean进行关系绑定(DI)
最终结果为:使用对象时不仅可以直接从IOC容器中获取,并且获取到的bean已经绑定了所有的依赖关系.

总结下来就是

(1) 什么IOC/DI思想?
IOC:控制反转,控制反转的是对象的创建权DI:依赖注入,绑定对象与对象之间的依赖关系
(2) 什么是IOC容器?
Spring创建了一个容器用来存放所创建的对象,这个容器就叫IOC容器
(3)什么是Bean?
容器中所存放的一个个对象就叫Bean或Bean对象

IOC的一个简单案例

直接来看一下简单的操作吧!理论思想太多就很烦人了。

那我们可以先创建一个简单的maven 模块。
我们要用Spring 的话,就需要去在依赖中导入模块。

我们来看pom中需要导入什么

<?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>org.example</groupId>
    <artifactId>SpringPratice</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>

</project>

在这里插入图片描述

在这里插入图片描述
我们的项目的java代码。
在这里插入图片描述

package jgdabc.dao;

public interface BookDao {
    public void save();
}

package jgdabc.dao.impl;

import jgdabc.dao.BookDao;

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

package jgdabc.service;

public interface BookService {
    public void save();
}

package jgdabc.service.impl;

import jgdabc.dao.BookDao;
import jgdabc.dao.impl.BookDaoImpl;
import jgdabc.service.BookService;

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


        public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

}

其实在这之前我们需要配置一下spring的配置文件。
在这里插入图片描述

<?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">

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


    </bean>
</beans>

至于相关标签上面注释说的很明白了。我们需要记住的是bean一定是和对象相关联的。

我们先使用这一部分。

在这里插入图片描述
我们这样去获取一个ioc容器,然后获取到对象,我们就可以实现对对象的调用。

import jgdabc.dao.BookDao;
import jgdabc.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
//        获取ioc容器(控制反转的)
     ApplicationContext ctx =  new ClassPathXmlApplicationContext("ApplicationContext.xml");
//     获取bean
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }

}

当然你可以先运行这一段

import jgdabc.dao.BookDao;
import jgdabc.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
//        获取ioc容器(控制反转的)
     ApplicationContext ctx =  new ClassPathXmlApplicationContext("ApplicationContext.xml");
//     获取bean
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();
//        BookService bookService = (BookService) ctx.getBean("bookService");
//        bookService.save();
    }

}

其实这里主要说明了,我可以获取到这个对象。当然这和配置是紧密相连的。另外从这里我们也可以知道ioc容器可以管理我们的bean对象。

我们还有新的问题就是,现在的service层,还是需要进行new对象。好下面我们对其解耦。

DI(依赖注入)案例

在这里插入图片描述
对的,这样是有道理的。但是我们如何给它传呢?依赖注入!

在这里插入图片描述
所以这里的改变在于service层实现类和配置的依赖注入。
具体如下。

<?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">

<!--    bean标签表示配置配置bean-->
<!--    id属性表示给bean起名字-->
<!--    class属性表示给bean定义类型-->
    <bean id="bookDao" class="jgdabc.dao.impl.BookDaoImpl"></bean>
    <bean id="bookService" class="jgdabc.service.impl.BookServiceImpl">
<!--        配置server与dao的关系-->
        <property name="bookDao" ref="bookDao"></property>
<!--        property 表示配置当前bean的属性-->
<!--        name配置配置哪一个具体的属性-->
<!--        ref属性表示参照哪一个bean-->

    </bean>
</beans>
package jgdabc.service.impl;

import jgdabc.dao.BookDao;
import jgdabc.dao.impl.BookDaoImpl;
import jgdabc.service.BookService;

public class BookServiceImpl implements BookService {
//    删除业务层当中使用new的方式创建的对象
//        private BookDao bookDao = new BookDaoImpl();
          private BookDao bookDao;
//          生成一个set方法

//
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

}

然后测试

import jgdabc.dao.BookDao;
import jgdabc.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {
    public static void main(String[] args) {
//        获取ioc容器(控制反转的)
     ApplicationContext ctx =  new ClassPathXmlApplicationContext("ApplicationContext.xml");
     获取bean
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }

}

在这里插入图片描述

有关bean

bean 基础配置

在这里插入图片描述
首先关注一下class属性。我们之前一般都是写接口的实现类类名。来让其创建出,并管理对象。但是我们可能有一个疑惑。class 指定为什么不能直接写接口名呢?

hh,当然是因为接口是不能创建对象的,创建对象的工作,我们在以前也学过,一定是需要其实现类来完成。所以在配置这里,同样也是不能指定接口的全类名来进行配置。

还有就是bean的id。id一般是一定是唯一的。有没有可以重命名的办法。有的,办法就是进行指定name属性。向下面这样。
在这里插入图片描述

那么在获取bean的时候你也可以通过这个来获取。

bean的scope配置

在这里插入图片描述

scope是用来指定是单例还是非单例。单例就是你通过IOC来造的对象在每次创建都是同一个对象,也就是地址是一样的。非单例则反之。

在这里指定就好。
在这里插入图片描述

当然你可以在代码中验证一下IOC中的bean是单例还是非单例。
现在不指定scope,看默认是单例还是非单例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看的出是一样的。
那么我们现在指定。

在这里插入图片描述
你看地址是不一样了。
关于中间那句是我对bean实例的一次测试。
在这里插入图片描述

那么后面我们来看bean如何实例以及其相关的特点。

bean的实例化

我们明白的是Spring 的IOC容器为我们创建了对象。我们需要了解到的是它是如何创建的对象。

而我们通常把创建对象的过程叫做对象的实例化,bean的本质就是对象,那么一定会调用构造方法。至于无参还是有参,我们可以简单验证。
我们需要写几个类来测试一下。
dao层接口类

package jgdabc.dao;

public interface BookDao {
    public void save();
}

package jgdabc.dao.impl;

import jgdabc.dao.BookDao;

public class BookDaoImpl implements BookDao {
    public BookDaoImpl() {
        System.out.println("book dao constructor is running...");
    }

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

我们在dao层实现类中写一个构造方法。因为我们将来在service层调用这个属于这个类的bean。

现在我们写service层的接口和实现类

package jgdabc.service;

public interface BookService {
    public void save();
}

package jgdabc.service.impl;

import jgdabc.dao.BookDao;
import jgdabc.dao.impl.BookDaoImpl;
import jgdabc.service.BookService;

public class BookServiceImpl implements BookService {
//    删除业务层当中使用new的方式创建的对象
//        private BookDao bookDao = new BookDaoImpl();
          private BookDao bookDao;
//          生成一个set方法

//
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

}

然后我们在配置文件当中,还是那样写。
在这里插入图片描述
然后测试,注意我们这里一共有两个bean,我们一定要明白的是如果构造方法执行的话,一定会执行两次。我们来验证。

在这里插入图片描述

在这里插入图片描述
我们看到构造方法被调用了,由此可见,实例化的时候,这个无惨构造方法被调用了。

如果我们把这个构造方法

—未完续更。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-01 15:02:20  更:2022-06-01 15:04:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 11:18:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码