Spring简介IOCDI

2024-05-13 17:52
文章标签 java spring 简介 iocdi

本文主要是介绍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{@Overridepublic 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{@Overridepublic 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;@Overridepublic void save() {System.out.println("BookService save...");}@Overridepublic 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 无参构造...");}@Overridepublic 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();}@Overridepublic 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();}
}

这篇关于Spring简介IOCDI的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/986404

相关文章

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Java判断多个时间段是否重合的方法小结

《Java判断多个时间段是否重合的方法小结》这篇文章主要为大家详细介绍了Java中判断多个时间段是否重合的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录判断多个时间段是否有间隔判断时间段集合是否与某时间段重合判断多个时间段是否有间隔实体类内容public class D

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Spring AI集成DeepSeek的详细步骤

《SpringAI集成DeepSeek的详细步骤》DeepSeek作为一款卓越的国产AI模型,越来越多的公司考虑在自己的应用中集成,对于Java应用来说,我们可以借助SpringAI集成DeepSe... 目录DeepSeek 介绍Spring AI 是什么?1、环境准备2、构建项目2.1、pom依赖2.2