Spring简介IOCDI

文章目录

  • Spring简介
    • Spring课程介绍
      • 为什么要学
      • 学什么
      • 怎么学
    • 初识Spring
      • Spring家族
      • Spring发展史
    • Spring体系结构
    • Spring核心概念
      • 目前代码存在的问题
      • 核心概念
  • IOC和DI入门案例
    • IOC入门案例
      • 入门案例分析
      • 实现步骤
      • 实现代码
    • DI入门案例
      • DI入门案例分析
      • 实现步骤
      • 实现代码
      • 图解演示
  • Bean的基础配置
    • bean基础配置
      • id
      • class
    • bean别名配置
      • name
    • bean作用范围配置
      • scope
  • Bean的实例化
    • bean是如何创建的
    • 实例化bean的三种方式
      • 构造方法方式(重点)
      • 静态工厂方式(了解)
      • 实例工厂方式(了解)
      • 实现FactoryBean<T>方式(扩展,了解)
  • 依赖注入
    • 依赖注入方式
      • setter注入
      • 构造器注入(了解)
      • 方式选择
    • 依赖自动装配
    • 集合注入
  • Bean的生命周期
    • 生命周期相关概念介绍
    • bean的生命周期
      • 初始化容器
      • 使用bean
      • 关闭/销毁容器
    • 代码演示
      • bean生命周期演示
      • bean生命周期控制--接口控制(了解)
    • bean销毁时机

Spring简介

Spring课程介绍

为什么要学

  • Spring技术是JavaEE开发必备技能,企业开发技术选型命中率>=90%
  • 专业角度
    • 简化开发,降低企业级开发的复杂性
    • 框架整合,高效整合其他技术,提高企业级应用开发与运行效率

学什么

  • 简化开发
    • IOC
    • AOP(面向切面编程)
      • 事务处理

怎么学

  • 学习Spring框架设计思想
  • 学习基本操作,思考操作与思想间的联系
  • 学习案例,熟悉应用操作的同时,体会思想

初识Spring

Spring家族

  • 官网(中文):https://spring.p2hp.com/index.html
  • Spring发展到今天已经形成了一种开发的生态圈,Spring提供了若干个项目,每个项目用于完成特定的功能

image.png

Spring发展史

image.png

Spring体系结构

4.0
image.png

Spring核心概念

目前代码存在的问题

在不同的类中使用对象得先new对象,然后再进行使用
另外接口中要是实现类变量,等号右边也得改变
问题:这样耦合度偏高
解决方案:使用对象时,在程序中不要主动new对象,转换为由外部提供对象

核心概念

  • IOC(Inversion of Control)控制反转

使用对象时,由主动new产生对象转换为由外部提对 象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转。

  • Spring对Ioc思想进行了实现
    • Spring提供了一个容器,称为IOC容器,用来充当Ioc思想中的"外部"
    • IOC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在Ioc容器中统称为Bean
  • DI(Dependency Injection)依赖注入
    • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入

image.png

  • 目标充分解耦
    • 使用Ioc容器管理bean
    • 在Ioc容器内将有依赖关系的bean进行关系绑定
  • 最终效果
    • 使用对象时不仅可以直接从Ioc容器中获取,并且获取到的bean已经绑定了所有的依赖关系

IOC和DI入门案例

IOC入门案例

入门案例分析

  1. 管理什么?(Service与Dao)
  2. 如何将被管理的对象告知IOC容器?(配置文件)
  3. 被管理的对象交给IOC容器,如何获取到IoC容器?(接口)
  4. IOC容器得到后,如何从容器中获取bean?(接口方法)
  5. 使用Spring导入哪些坐标?(pom.xml)

实现步骤

  1. 导入Spring坐标
  2. 定义Spring管理的类(接口)
  3. 创建Spring配置文件,配置对应类作为Spring管理的bean对象
  4. 初始化IOC容器(Spring核心容器/Spring容器),通过容器获取bean

实现代码

  1. 坐标
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.10.RELEASE</version>
    </dependency>
  1. 定义接口
//接口
public interface BookService {

    void save();
}
//实现类
public class BookServiceImpl implements BookService{
    @Override
    public void save() {
        System.out.println("BookService save...");
    }
}

  1. 创建配置文件
<?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 id="bookService" class="org.example.service.BookServiceImpl"></bean>
</beans>

bean定义id属性在同一个上下文中(IOC容器中)不能重复

  1. 初始化ioc容器,通过容器获取bean对象
public class App {
    public static void main( String[] args ) {

        //1.创建IOC容器,加载Spring核心配置文件
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.从IOC容器中获取bean对象(BookService对象)
        BookService bookService = (BookService) ctx.getBean("bookService");
        //3.调用Bean对象(BookService)的方法
        bookService.save();
    }
}

DI入门案例

DI入门案例分析

  1. 基于IOC管理bean
  2. Service中使用new形式创建的Dao对象是否保留?(否)
  3. Service中需要的Dao对象如何进入到Service中?(提供set方法)
  4. Service与Dao间的关系如何描述?(配置)

实现步骤

  1. 删除使用new的形式创建对象的代码
  2. 提供依赖对象对应的setter方法
  3. 配置service与dao之间的关系

实现代码

  1. 先创建BookDao接口以及实现类
public interface BookDao {

    void save();
}

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

  1. 在BookService的接口和实现类中提供依赖对象对应的setter方法
public interface BookService {

    void save();

    void setBookDao(BookDao bookDao);
}

public class BookServiceImpl implements BookService{

    private BookDao bookDao;
    @Override
    public void save() {
        System.out.println("BookService save...");
    }

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

}

  1. 在配置文件中配置service和dao的关系
<?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 id="bookService" class="org.example.service.BookServiceImpl">
        <property name="bookDao" ref="bookDao"></property>
    </bean>

    <bean id="bookDao" class="org.example.dao.BookDaoImpl"></bean>
</beans>

图解演示

image.png

Bean的基础配置

bean基础配置

id

使用容器通过id值获取对应的bean,在一个容器中id值唯一

class

bean的类型,即配置bean的全路径类名(实体类)

bean别名配置

name

定义bean的别名,可定义多个,使用逗号,空格,分号隔开
在通过applicationContext获取bean时,也可以通过别名获取

bean作用范围配置

scope

定义bean的作用范围

  • singleton:单例(默认)
  • prototype:非单例

扩展:scope的取值不仅仅只有singleton和prototype,还有request、session、application、 websocket ,表示创建出的对象放置在web容器(tomcat)对应的位置。比如:request表示保存到request域中。

Bean的实例化

bean是如何创建的

bean本质上就是对象,创建bean使用构造方法完成

实例化bean的三种方式

构造方法方式(重点)

  1. BookDaoImpl实现类
public class BookDaoImpl implements BookDao{

    public BookDaoImpl(){
        System.out.println("bookDaoImpl 无参构造...");
    }
    @Override
    public void save() {
        System.out.println("BookDao save...");
    }
}

  1. 配置文件
    <bean id="bookDao" class="org.example.dao.BookDaoImpl"></bean>
  1. main方法
  //1.创建IOC容器,加载Spring核心配置文件
  ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  //2.从IOC容器中获取bean对象(BookService对象)
  BookDao bookDao = (BookDao) ctx.getBean("bookDao");
  //3.调用Bean对象(BookService)的方法
  bookDao.save();
  1. 运行结果

image.png
说明默认使用是无参构造方法
:无参构造方法如果不存在,会报错

静态工厂方式(了解)

  1. 删除BookDao实现类的无参构造方法
  2. 创建一个类书写静态工厂的代码
public class StaticFactory {

    public static BookDao getBookDao(){

        System.out.println("静态工厂...");
        return new BookDaoImpl();
    }
}

  1. 配置文件(将之前的注释掉或删掉)
   <bean id="bookDao" class="org.example.factory.StaticFactory" factory-method="getBookDao"></bean>

实例工厂方式(了解)

  1. 创建一个类书写实例工厂的代码
  2. 配置文件(之前的注释掉)
    <bean id="InstanceDaoFactory" class="org.example.factory.InstanceFactory" ></bean>
    <bean id="bookDao"  factory-bean="InstanceDaoFactory" factory-method="getBookDao"></bean>

实现FactoryBean方式(扩展,了解)

实例化工厂的一种方式

  1. 书写类实现FactoryBean
public class BookDaoFactory implements FactoryBean {
    @Override
    //代替原始实例工厂中创建对象的方法
    public Object getObject() throws Exception {

        System.out.println("FactoryBean ...");
        return new BookDaoImpl();
    }

    @Override
    public Class<?> getObjectType() {
        return BookDao.class;
    }
}

  1. 配置文件
 <bean id="bookDao" class="org.example.factory.BookDaoFactory"></bean>

依赖注入

依赖注入方式

setter注入

要先提供对应的set方法

  1. 引用类型

配置文件中property标签ref属性注入引用类型对象

  1. 简单类型

配置文件中property标签value属性注入引用类型对象

构造器注入(了解)

要先书写对应的构造方法

  1. 引用类型

配置文件中constructor-arg标签ref属性注入引用类型对象

  1. 简单类型

配置文件中constructor-arg标签value属性注入引用类型对象

  1. 参数适配

也可以使用constructor-arg标签中type属性按形参类型注入或index属性按形参位置注入

方式选择

自己开发的模块推荐使用setter方式注入,如果受控对象没有提供setter方法就必须使用构造器注入

依赖自动装配

配置中使用bean标签的autowire属性设置自动装配的类型
使用按类型装配,必须保障容器中相同类型的bean唯一

  <bean id="bookService" class="org.example.service.BookServiceImpl" autowire="byType">
<!--        <property name="bookDao" ref="bookDao"></property>-->
    </bean>

    <bean id="bookDao" class="org.example.dao.BookDaoImpl"></bean>

集合注入

注入数据类型,List类型,Set类型,Map类型,Properties类型

<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>

说明:property标签标识setter注入,构造方式注入constructor-arg标签内部也可以写、、、标签

Bean的生命周期

生命周期相关概念介绍

  • 生命周期:从创建到消亡的完整过程
  • bean生命周期:bean从创建到销毁的整体过程
  • bean生命周期控制:在bean创建后到销毁前做一些事情

bean的生命周期

初始化容器

  1. 创建对象
  2. 执行构造方法
  3. 执行属性注入(set注入)
  4. 执行bean初始化方法

使用bean

  1. 执行业务操作

关闭/销毁容器

  1. 执行bean销毁方法

代码演示

bean生命周期演示

  • 提供生命周期控制方法
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
    //表示bean初始化对应的操作
    public void init(){
        System.out.println("init...");
    }
    //表示bean销毁前对应的操作
    public void destory(){
        System.out.println("destory...");
    }
}
  • 配置文件
<!--init-method:设置bean初始化生命周期回调函数,此处填写init方法名-->
<!--destroy-method:设置bean销毁生命周期回调函数,仅适用于单例对象,此处填写destory方法名-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
  • 测试类
public class AppForLifeCycle {
    public static void main( String[] args ) {
        //此处需要使用实现类类型,接口类型没有close方法
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();
        //关闭容器,执行销毁的方法
        ctx.close();
    }
}

bean生命周期控制–接口控制(了解)

  • 实现InitializingBean, DisposableBean接口
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        System.out.println("set .....");
        this.bookDao = bookDao;
    }
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    public void destroy() throws Exception {
        System.out.println("service destroy");
    }
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
    }
}
  • 不需要在配置文件中bean标签中写init-method属性和destory-method属性

bean销毁时机

  • 容器关闭前触发bean的销毁
  • 关闭容器的方式
    • 手工关闭容器

ConfigurableApplicationContext接口**close()**操作

  • 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机

ConfigurableApplicationContext接口**registerShutdownHook()**操作


public class AppForLifeCycle {
    public static void main( String[] args ) {
        //此处需要使用实现类类型,接口类型没有close方法
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();
        //注册关闭钩子函数,在虚拟机退出之前回调此函数,关闭容器
        ctx.registerShutdownHook();
        //关闭容器
        //ctx.close();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/620785.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

美业收银系统源码-App/iPad/PC管理系统常见问题讲解(1)

博弈美业管理系统源码 连锁多门店美业收银系统源码 多门店管理 / 会员管理 / 预约管理 / 排班管理 / 商品管理 / 促销活动 PC管理后台、手机APP、iPad APP、微信小程序 1、平板iPad的评论内容&#xff0c;是从哪里评论的呢&#xff1f; 顾客在接受服务后&#xff0c;可以到…

这些小众软件让你秒变职场高手

工作繁忙&#xff0c;效率不高&#xff1f;别急&#xff0c;今天就要给你种草几款超实用的小众工作软件&#xff0c;让你的办公桌面焕然一新&#xff0c;效率翻倍&#xff01;&#x1f440; 1️⃣《亿可达》 &#x1f5a5;️ 它是一款自动化工具&#xff0c;相当于国内版免费…

Pytorch如何计算网络参数

方法一. 利用pytorch自身 PyTorch是一个流行的深度学习框架&#xff0c;它允许研究人员和开发者快速构建和训练神经网络。计算一个PyTorch网络的参数量通常涉及两个步骤&#xff1a;确定网络中每个层的参数数量&#xff0c;并将它们加起来得到总数。 以下是在PyTorch中计算网…

Secnet-智能路由系统 actpt_5g.data 信息泄露漏洞复现

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司&#xff08;简称“安网通信”&#xff09;的无线AP管理系统。 0x02 漏洞概述 Secnet-智能路由系统 actpt_5g.data 接口存在信息泄露漏洞&#xff0c;未经身份验证的远程攻击者可以利用此漏洞获取系统账户…

免费吃外卖美团饿了么霸王餐cps返利h5公众号小程序开源版开发

免费吃外卖美团饿了么霸王餐cps返利h5公众号小程序开源版开发 外卖点餐高额返现、无需招商、无需垫资均、佣金35%~61%、私域运营持续稳定。 价格实惠低成本创业、配置简单最快10分钟上线、个体企业都可创建、H5小程序公众号、 2024新风向高佣才是硬道理。 01业务简介 业务模…

【一触即发】快来围观C3安全大会酷炫九宫格!

C3安全大会2024 2024年5月18日 南京扬子江国际会议中心 C3安全大会2024 即将揭幕&#xff01; 图解C3 | 九宫格 数智变革&#xff0c;“AI”正以其颠覆性力量&#xff0c;重塑我们对未来的定义。亚信安全邀您共襄盛举&#xff0c;见证这场于5月18日盛大开幕的C3安全大会2024…

精酿之魂:精酿啤酒的酿造工艺与技术

啤酒&#xff0c;作为世界上古老的酒精饮品&#xff0c;其酿造工艺与技术经历了数千年的发展和演变。而在这一过程中&#xff0c;精酿啤酒逐渐崭露头角&#xff0c;成为了啤酒界的璀璨明星。作为精酿啤酒的品牌&#xff0c;Fendi club啤酒凭借其与众不同的酿造工艺与技术&#…

C++下使用Matplotlib-cpp的一些配置

Aconda3安装使用 https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/下载 切换清华源 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ con…

Peter算法小课堂—序列切割

讲序列切割之前&#xff0c;先来个铺垫 高手集训 题目描述&#xff1a; 课程表里有连续的n天可以供你选择&#xff0c;每天都有专题课程。其中第i天的专题趣味程度为h[i]。假设你选择了其中连续的若干天&#xff0c;从第l天到第r天。那么&#xff0c; 训练效果 h[l]*1 h[…

RS2105XN功能和参数介绍及PDF资料

RS2105XN 品牌: RUNIC(润石) 封装: MSOP-10 开关电路: 单刀双掷(SPDT) 通道数: 2 工作电压: 1.8V~5.5V 导通时间(Tonmax): 50ns RS2105XN是一款模拟开关芯片。以下是RS2105XN的功能和参数介绍&#xff1a; 功能&#xff1a; 2通道单刀双掷&#xff08;SPDT&#xff09;模拟开关…

抱怨无用,行动破局

故事的开始 这个专栏&#xff0c;以及本文的目的&#xff0c;是为了记录我从创立盘多啦这个平台开始&#xff0c;到后续的发展历程的专栏。同时也是给自己一个坚持的动力和警醒的作用。 首先&#xff0c;我是一名程序员&#xff0c;并且对于自身感兴趣的东西&#xff0c;都有…

使用Git管理github的代码库-上

1、下载安装Git https://download.csdn.net/download/notfindjob/11451730?spm1001.2014.3001.5503 2、注册一个github的账号&#xff08;已经注册的&#xff0c;可略过这一步&#xff09; 3、打开git命令行&#xff0c;配置github账号 git config --global user.name &quo…

自动化测试需知的4项测试工具

一般来说学自动化会建议大家先学selenium&#xff0c;因为最早的时候&#xff0c;自动化就代表selenium&#xff0c;进入测试行业就开始做接口测试&#xff0c;而且现在基本每个公司都需要接口测试。今天就和大家聊一下接口测试的工具。 一、Robot Framework 机器人框架。之所…

Bean的生命周期与循环依赖

如有不对的地方&#xff0c;还请大佬指正 Bean生命周期 扫描类 得到 BeanDefinition(包含bean的class等属性值) 后在BeanFactoryPostProcessor对bean实例化之前对Bean的元数据进行操作&#xff0c;修改Bean的属性值、添加自定义的BeanDefinition 实例化非懒加载单例bean1. …

秋招算法题——怪盗基德的滑翔翼

文章目录 题目描述思路分析思维误区 实现代码思路总结 题目描述 思路分析 注意点 只能从高到低方向一旦选择了&#xff0c;就确定了 问题转换 一旦确定了方向和起点后&#xff0c;就变为求以出发点为结尾的最长上升子序列是多少相当于同时确定两遍最长上升子序列&#xff0…

【python】模块与包

Python中的模块和包是组织和管理代码的重要工具。通过模块和包&#xff0c;你可以更好地管理和重用你的代码&#xff0c;使得代码更加模块化和可维护。 目录 前言 正文 一、模块 1、模块的分类 1&#xff09;内置模块 python解释器中默认拥有的模块可以直接使用&#xff08;…

力扣HOT100 - 70. 爬楼梯

解题思路&#xff1a; 动态规划 注意 if 判断和 for 循环 class Solution {public int climbStairs(int n) {if (n < 2) return n;int[] dp new int[n 1];dp[1] 1;dp[2] 2;for (int i 3; i < n; i) {dp[i] dp[i - 1] dp[i - 2];}return dp[n];} }

Maven 自动化构建

优质博文&#xff1a;IT-BLOG-CN 一、Maven&#xff1a;是一款服务于 Java平台的自动化构建工具 【1】Maven可以将一个项目按模块划分成不同的工程&#xff0c;利于分工协作; 【2】Maven可以将 jar包保存在自己的中央“仓库”中进行统一管理&#xff0c;有需要使用的工程引用这…

深入探究MySQL常用的存储引擎

前言 MySQL是一个广泛使用的开源关系型数据库管理系统&#xff0c;它支持多种存储引擎。存储引擎决定了MySQL数据库如何存储、检索和管理数据。不同的存储引擎具有不同的特点、性能表现和适用场景。选择适合的存储引擎对于优化数据库性能、确保数据完整性和安全性至关重要。本…

Pytorch基础:torch.cuda.set_device函数

相关阅读 Pytorch基础https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 torch.cuda.set_device函数用于设置当前使用的cuda设备&#xff0c;在当拥有多个可用的GPU且能被pytorch识别的cuda设备情况下&#xff08;环境变量CUDA_VISIBLE_…