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知识库 -> Spring-IoC(XML配置文件形式) -> 正文阅读

[Java知识库]Spring-IoC(XML配置文件形式)

目录

概述

配置文件加载bean(IoC入门)

IoC中设置依赖(DI入门)

Bean的作用范围

Bean的实例化方式

方式一:使用空参构造器(默认)

?方式二:静态工厂

方式三:实例工厂

方式四:Factory Bean(对"实例工厂的优化")

?Bean的生命周期

控制生命周期

关闭IoC容器的方式

?依赖注入的方式

setter方式注入

构造器注入

?依赖自动装配


概述

IoC(Inversion of control) 控制反转,是一种思想。

IoC思想:为了解耦,在程序中不直接new获得对象,而是由外部提供对象(控制反转)。如果我们直接通过new的方式获得对象,需要清楚所有的底层对象初始化过程进行依赖处理,才能进行逻辑处理,而通过IoC引入的对象(外部提供),我们通过依赖注入(DI)的方式进行依赖处理就行。

?spring技术对IoC思想进行了实现。称为 IoC容器

IoC容器从当IoC思想中的"外部",用来负责对象的创建、初始化等一系列工作,在IoC容器中的对象统称为bean。

DI(Dependency Injection)依赖注入

?在IoC容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入。

使用对象不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系。

配置文件加载bean(IoC入门)

测试用的包结构?

1.使用spring-IoC我们需要导入坐标:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.18</version>
</dependency>

2.创建配置文件,在配置文件中加载bean

?3.在IoC中创建bean

?4.获取IoC中的bean

public class mainTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext();
        //通过设置的id获取bean
        UserDAO userDAO = (UserDAO) context.getBean("userDAO");
        //bean调用方法
        userDAO.save();
    }
}

IoC中设置依赖(DI入门)

目录结构?

userService中引用UserDAO,并且使用其中的方法。

(使用依赖注入形式,原始是new之后使用new的对象调用其中的方法)

1.引入 依赖

?

?2.设置set方法(相当于是一个入口)

?

?3.到配置文件中设置依赖映射(解决依赖)


<bean id="userServiceImpl" class="com.mh.service.UserServiceImpl">
    <!--配置依赖--注意ref,不是value-->
    <!--name值要和引入依赖时属性名相同-->
    <property name="userDAO" ref="userDAO"></property>
</bean>

<!--依赖加入bean-->
<bean id="userDAO" class="com.mh.dao.UserDAOImpl"></bean>

4.测试方法即可。

Bean的作用范围

?在IoC中定义的bean,默认为单例模式scope:singleton

?设置bean的方式:在<bean> 中添加属性scope

Bean的实例化方式

方式一:使用空参构造器(默认)

在上述案例中均使用此方式构造bean,使用了默认的空参构造器。

?方式二:静态工厂

方式三:实例工厂

跟静态工厂很相似,实例工厂是非静态的,所以需要先将工厂加载到IoC容器中。?

方式四:Factory Bean(对"实例工厂的优化")

?

?Bean的生命周期

提到bean的生命周期,也就是在bean创建时或销毁时做一些事情。

控制生命周期

方式一:使用配置(非标准化)

就是在类中声明两个方法,初始化和销毁的方法,将两个自定义的方法配置到<bean>中。

未控制声明周期时执行

测试代码

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//测试userDAO方法,无依赖,测试成功
UserDAO userDAO = (UserDAO) context.getBean("userDAO");
userDAO.save();

执行结果?

?设置声明周期的控制

在类中声明方法

public class UserDAOImpl implements UserDAO{

    @Override
    public void save() {
        System.out.println("UserDAO...");
    }

    //自定义初始化和销毁方法
    public void init(){
        System.out.println("初始化方法加载...");
    }

    public void destroy(){
        System.out.println("销毁方法加载...");
    }
}

将方法加载到配置中

?再次测试执行结果:

?会发现一个问题,两个方法,只有初始化方法执行,销毁的方法并没有生效。

方式二:使用接口(标准化)

使用两个接口,实现其中的方法,两个接口分别对应着初始化和销毁的方法。

public class UserDAOImpl implements UserDAO, InitializingBean, DisposableBean {

    @Override
    public void save() {
        System.out.println("UserDAO...");
    }
    
    //销毁方法
    @Override
    public void destroy() throws Exception {

    }
    
    //初始化方法(在属性之后执行)
    @Override
    public void afterPropertiesSet() throws Exception {
        
    }
}

执行测试方法,和方式一 一样:

?两种方法可以看出,只有初始化方法执行,销毁的方法没有被执行,也就是声明周期并没有在虚拟机关闭前自动的调用销毁方法,所以我们只能手动将IoC容器关闭,才会执行销毁方法。

关闭IoC容器的方式

1.手动关闭容器

具体使用:close()

测试代码

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//测试userDAO方法,无依赖,测试成功
UserDAO userDAO = (UserDAO) context.getBean("userDAO");
userDAO.save();
//手动关闭容器
context.close();

测试代码执行结果(销毁方法执行)

2.注册钩子?

测试代码?

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDAO userDAO = (UserDAO) context.getBean("userDAO");
userDAO.save();
context.registerShutdownHook();

?测试代码执行结果和手动关闭结果一致

手动关闭和注册钩子的方式说明:手动关闭需要考虑书写的位置,一般写到代码最后,而注册钩子则没有书写位置要求。

?依赖注入的方式

setter方式注入

引用数据类型?

setter注入,就是给需要的依赖设置set方法,包括基本数据类型和引用数据类型。

依赖:userDAO ,设置set方法

public class UserServiceImpl implements UserService{
    
    //引用数据类型
    private UserDAO userDAO;
    
    //设置set方法    
    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public void save() {
        //在其中调用userDAO(依赖)
        userDAO.save();
        System.out.println("userService...");
    }
}

?配置依赖

<bean id="userDAO" class="com.mh.dao.UserDAOImpl"></bean>
<bean id="userServiceImpl" class="com.mh.service.UserServiceImpl">
    <property name="userDAO" ref="userDAO"></property>
</bean>

简单数据类型

?设置简单数据类型依赖,并且设置set方法

public class UserDAOImpl implements UserDAO {
    
    //设置简单数据类型依赖
    private String uname;
    
    //设置set方法
    public void setUname(String uname) {
        this.uname = uname;
    }
    
    @Override
    public void save() {
        System.out.println("UserDAO..." + uname);
    }
}

配置依赖

<bean id="userDAO" class="com.mh.dao.UserDAOImpl">
    <!--使用value属性赋值-->
    <property name="uname" value="Tom"/>
</bean>

构造器注入

类中设置简单数据类型和构造器

public class GoodsDAOImpl  implements GoodsDAO {

    int num;

    public GoodsDAOImpl(int num){
        this.num = num;
    }

    @Override
    public void save() {
        System.out.println("goods..." + num );
    }
}
<bean id="goodsDAO" class="com.mh.dao.GoodsDAOImpl">
	<constructor-arg name="num" value="100"/>
</bean>

类型装配

此方式存在紧耦合(属性名字需要一致),不利于使用。解决方式:使用类型进行装配

<bean id="goodsDAO" class="com.mh.dao.GoodsDAOImpl">
    <constructor-arg type="int" value="100"/>
</bean>

此方式解决了名字的耦合问题,但是存在:万一数据类型不唯一的情况就不可用。

比如存在两个int类型的情况。这种情况下:就可以使用索引进行装配。

索引装配

<bean id="goodsDAO" class="com.mh.dao.GoodsDAOImpl">
    <constructor-arg index="0" value="100"/>
</bean>

依赖注入的方式选择?

?依赖自动装配

IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配

?自动装配的方式:

1.按类型装配

2.按名称装配

?自动装配特征

  • 自动装配用于引用类型依赖注入,不能简单类型进行操作。
  • 使用按类型装配时,必须保障容器中相容类型的bean唯一。
  • 使用按名称装配时,必须保障容器中具有指定名称的bean。
  • 自动装配优先级低于setter注入与构造器注入。两者使用可能会发生冲突导致报错。
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 11:40:47  更:2022-10-31 11:45:10 
 
开发: 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年5日历 -2024/5/19 9:08:16-

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