Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式

news2025/4/15 7:09:28

目录

一、对象的创建方式

1. 使用构造方法

2. 使用工厂类方法

3. 使用工厂类的静态方法

二、对象的创建策略

1. 单例策略

2. 多例策略

三、对象的销毁时机

四、生命周期方法

1. 定义生命周期方法

2. 配置生命周期方法

3. 测试

五、获取Bean对象的方式

1. 通过id/name获取

2. 通过类型获取

3. 通过类型+id/name获取

往期专栏&文章相关导读 


一、对象的创建方式

Spring会帮助我们创建bean,那么它底层是调用什么方法进行创建的呢?有以下三种方法

  1. 使用构造方法
  2. 使用工厂类方法
  3. 使用工厂类的静态方法

接下来详细讲解这三种方法。

1. 使用构造方法

        Spring默认使用类的空参构造方法创建bean,假如类没有空参构造方法,将无法完成bean的创建,接下来我们可以测试一下。

package com.example.dao;

import com.example.pojo.Student;

public class StudentDaoImpl1 implements StudentDao{

    /*public StudentDaoImpl1() {
    }*/

    public StudentDaoImpl1(int a){};
    @Override
    public Student findById(int id){
        return new Student(id,"程序员","北京");
    }
}

错误原因:Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'studentDao' defined in class path resource [bean.xml]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'int' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

翻译:上下文初始化过程中遇到异常-取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建类路径资源[bean.xml]中定义的名称为“studentDao”的bean时出错:通过构造函数参数0表示的不满足依赖关系;嵌套异常为org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的类型为“int”的符合条件的bean:应至少有1个符合自动连线候选条件的bean。依赖项注释:{}

其实就是没有空的构造函数,加上一个就好了

2. 使用工厂类方法

        Spring可以调用工厂类的方法创建bean:创建工厂类,工厂类提供创建对象的方法,在配置文件中配置创建bean的方式为工厂方式。

工厂类StudentDaoFactory:

package com.example.dao;

public class StudentDaoFactory {

    public StudentDao getStudentDao(){
        return new StudentDaoImpl1(1);
    }

}

bean.xml的配置:

    <!-- id: 工厂对象的id,class:工厂类 -->
    <bean id="studentDaoFactory" class="com.example.dao.StudentDaoFactory" />
    <!-- id:bean对象的id,factory-bean:工厂对象的id,factory-method:工厂方法 -->
    <bean id="studentDao" factory-bean="studentDaoFactory" factory-method="getStudentDao"></bean>

测试方法: 

    @Test
    public void t2(){
        // 创建spring容器
        ApplicationContext ac = new FileSystemXmlApplicationContext("C:\\JavaProjects\\06SSM_Projects\\springdemo\\spring_ioc1\\src\\main\\resources\\bean.xml");

        // 从容器中获取对象
        StudentDao userDao = ac.getBean("studentDao",StudentDao.class);
        System.out.println(userDao);
        System.out.println(userDao.findById(1));;
    }

测试结果: 

OK,确实成功写出来了 

3. 使用工厂类的静态方法

        Spring可以调用工厂类的静态方法创建bean,创建工厂类,工厂提供创建对象的静态方法,在配置文件中配置创建bean的方式为工厂静态方法。

工厂类StudentDaoFactory2

package com.example.dao;

public class StudentDaoFactory2 {
    public static StudentDao getStudentDao2() {
        return new StudentDaoImpl2();
    }
}

bean.xml的配置 

    <!-- id:bean的id class:工厂全类名 factory-method:工厂静态方法 -->
     <bean id="studentDao" class="com.example.dao.StudentDaoFactory2" factory-method="getStudentDao2"/>

都是可以成功运行的。 

二、对象的创建策略

        scope属性设置对象的创建策略。Spring通过配置 <bean> 中的 scope 属性设置对象的创建策略,共有两种种创建策略。

1. 单例策略

        singleton:单例,默认策略。整个项目只会创建一个对象,通过 <bean> 中的 lazy-init 属性可以设置单例对象的创建时机:lazy-init="false"(默认):立即创建,在容器启动时会创建配置文件中的所有Bean对象。lazy-init="true":延迟创建,第一次使用Bean对象时才会创建。下面测试获取对象后的哈希值是否一样就可以知道是否配置单例策略了

bean.xml的配置 

    <bean id="studentDao" class="com.example.dao.StudentDaoImpl2" scope="singleton" lazy-init="true" />

测试方法 

    @Test
    public void t3(){
        // 创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        // 从容器获取对象
        StudentDao studentDao1 = ac.getBean("studentDao",StudentDao.class);
        StudentDao studentDao2 = ac.getBean("studentDao",StudentDao.class);
        StudentDao studentDao3 = ac.getBean("studentDao",StudentDao.class);

        System.out.println(studentDao1.hashCode());
        System.out.println(studentDao2.hashCode());
        System.out.println(studentDao3.hashCode());
    }

运行结果 

        OK,得到的对象都是同一个哈希值,说明确实是同一个对象也就是说成功配置了单例模式。 

2. 多例策略

prototype:多例,每次从容器中获取时都会创建对象。

bean.xml配置 

<!-- 配置多例策略 -->
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl2" scope="prototype"></bean>

测试结果 

得到的哈希值不一样,说明得到的是不同的对象,确实是多例策略 。

request:每次请求创建一个对象,只在web环境有效。
session:每次会话创建一个对象,只在web环境有效。
gloabal-session:一次集群环境的会话创建一个对象,只在web环境有效。

三、对象的销毁时机

对象的创建策略不同,销毁时机也不同:

  1. singleton:对象随着容器的销毁而销毁。
  2. prototype:使用JAVA垃圾回收机制销毁对象。
  3. request:当处理请求结束,bean实例将被销毁。
  4. session:当HTTP Session最终被废弃的时候,bean也会被销毁掉。
  5. gloabal-session:集群环境下的session销毁,bean实例也将被销毁。

四、生命周期方法

        Bean对象的生命周期包含创建——使用——销毁,Spring可以配置Bean对象在创建和销毁时自动执行的方法:

1. 定义生命周期方法

在StudentDaoImpl2中新增生命周期方法

    // 创建时自动执行的方法
    public void init(){
        System.out.println("使用StudentDaoImpl2创建对象"+this.hashCode());
    }

    // 销毁时自动执行的方法
    public void destroy(){
        System.out.println("销毁StudentDaoImpl2创建的对象"+this.hashCode());
    }

2. 配置生命周期方法

    <!-- init-method:创建对象时执行的方法 destroy-method:销毁对象时执行的方法 -->
    <bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl2" scope="singleton" init-method="init" destroy-method="destory"></bean>

3. 测试

测试方法

@Test
public void t3(){
  // 创建Spring容器
  ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");
  // 销毁Spring容器,ClassPathXmlApplicationContext才有销毁容器的方法
  ac.close();
}

测试结果 

也确实可以 

五、获取Bean对象的方式

1. 通过id/name获取

获取对象的时候是这样:

StudentDao studentDao = (StudentDao) ac.getBean("studentDao");

2. 通过类型获取

获取对象的时候是这样:

StudentDao studentDao2 = ac.getBean(StudentDao.class);

不需要进行类型强转

3. 通过类型+id/name获取

        虽然使用类型获取不需要强转,但如果在容器中有一个接口的多个实现类对象,则获取时会报错,此时需要使用类型+id/name获取,获取对象是这样:

StudentDao studentDao2 = ac.getBean("studentDao",StudentDao.class);

往期专栏&文章相关导读 

     大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。

Maven系列专栏文章
Maven系列专栏Maven工程开发
Maven聚合开发【实例详解---5555字】
Mybatis系列专栏文章
Mybatis系列专栏MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发---实现增删查改和动态SQL
MyBatis注解开发---实现自定义映射关系和关联查询
Spring系列专栏文章
Spring系列专栏Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习ZLmediaKit流媒体服务器时候遇到的问题

照zlmediakit的源码 自己复制了一份 然后有的地方编译不过修改了部分 测试的时候发现有两个问题 第一是 ffmpeg的ffplay 能播放 vlc不能播放 第二个问题是directProxy设置为0的时候 推流的时候 然后用ffplay播放 只有音频没有视频 查了好久终于解决这个问题 第一个…

pytest 自动化框架搭建-生成一个报告(alluer)

简单的case跑通了&#xff0c;尝试生成报告 1、使用allure-pytest 安装pip3 install allure-pytest 2、使用--alluredir../allure-results 如下我是直接在pytest.ini文件中使用命令 如下生成文件夹和json格式的文件 二、生成allure报告 1、安装allure 我是使用的命令直接…

字节超全学习流程图流出,100天涨薪10k,从功能测试到自动化测试...

今年年初&#xff0c;由于经济压力让我下定决心进阶自动化测试&#xff0c;已经24的我做了3年功能测试&#xff0c;坐标广州薪资定格在8k&#xff0c;可能是生活过的太安逸&#xff0c;觉得8000的工资也够了。 但是生活总是多变的&#xff0c;女朋友的突然怀孕&#xff0c;让我…

thinkphp6(tp6)初步小尝试(记录一下)

thinkphp6&#xff08;tp6&#xff09;初步小尝试&#xff08;记录一下&#xff09; 一、服务器环境二、创建tp6项目三、配置apache四、创建应用五、各应用入口六、简单模板 一、服务器环境 操作系统&#xff1a;ubuntu-22.04.2-live-server-amd64集成xampp(Apache MariaDB …

Python学习10:计算三维空间某点距离原点的欧式距离(python123)

题目描述: 欧几里得度量&#xff08;euclidean metric&#xff09;&#xff08;也称欧氏距离&#xff09;是一个通常采用的距离定义。三维空间里点a和b的坐标如果分别为a(x1,y1,z1)、b(x2,y2,z2)&#xff0c;则ab的距离的计算机公式是dist(a,b) √( (x1-x2)^2(y1-y2)^2(z1-z2…

史上最全Maven教程(四)

文章目录 &#x1f525;Maven聚合开发_聚合关系&#x1f525;Maven聚合开发_继承关系&#x1f525;Maven聚合案例_搭建父工程 &#x1f525;Maven聚合开发_聚合关系 之前我们在Idea中开发时会将项目的所有包放在同一个工程当中。 ⭐ domain&#xff1a;定义实体类 ⭐ dao&…

learn_C_deep_7 (switch 语句的基本理解、case 的作用、break的作用switch、case 推荐规则)

目录 switch 语句的基本理解 case语句的深度理解 case 的作用 case语句的要求 break 的作用 switch case 推荐规则 规则一&#xff1a; 规则二&#xff1a; 小结&#xff1a; switch 语句的基本理解 switch是一种控制语句&#xff0c;用于控制程序流程的走向。在 swit…

Zookeeper系统模型介绍

目录 一、数据模型 二、 节点的类型 &#xff08;1&#xff09;持久节点 &#xff08;2&#xff09;持久顺序节点 &#xff08;3&#xff09;临时节点 &#xff08;4&#xff09;临时顺序节点 三、客户端命令行 &#xff08;1&#xff09;创建节点 &#xff08;2&…

k8s- kubernetes证书过期替换之kubeadm命令 certs renew all方式

k8s- kubernetes证书过期替换之kubeadm命令 certs renew all方式 大纲 基础概念证书替换测试使用kubeadm alpha certs renew all 更新证书重启所有组件和kubelet.service生成kubelet-client-current.pem证书测试替换后集群是否正常工作 基础概念 本次测试使用的k8s集群使用…

【代码随想录】刷题Day9 --- 我有自信讲清楚KMP的next原理

字符串 --- 找子串匹配算法_哈里沃克的博客-CSDN博客https://blog.csdn.net/m0_63488627/article/details/130197908?spm1001.2014.3001.5501 首先具体KMP算法理论在上面的博客中&#xff0c;不过该博客我当初写的时候并没有了解next数组实现的过程是那样的&#xff0c;所以只…

【react全家桶学习】react中组件的props属性(详)

学过了vue的props属性&#xff0c;那react中的props属性如何使用呢&#xff1f; props的基本使用 我们先定义一个person组件 我们想要这三个参数动态传递进来&#xff0c;如何实现&#xff1f; 答&#xff1a;跟vue一样&#xff0c;直接在引用组件的地方进行传递即可。 在re…

Java——两个链表的第一个公共节点

题目链接 牛客网在线oj题——两个链表的第一个公共节点 题目描述 输入两个无环的单向链表&#xff0c;找出它们的第一个公共结点&#xff0c;如果没有公共节点则返回空。&#xff08;注意因为传入数据是链表&#xff0c;所以错误测试数据的提示是用其他方式显示的&#xff0…

润本“带伤”冲刺IPO,再闯“驱蚊第一股”

夏日来临&#xff0c;润本再度冲刺“驱蚊第一股”&#xff01; 今年3月&#xff0c;润本生物技术股份有限公司&#xff08;下称“润本”&#xff09;再次更新招股书&#xff0c;拟在上交所主板上市。 润本是一家多品牌家庭护理产品公司&#xff0c; 专注于驱蚊类、个人护理类…

米哈游新游正式公测!还没上线就已经“爆了”!

米哈游制作的3D冒险主题回合制策略游戏《崩坏&#xff1a;星穹铁道》&#xff0c;在2023年4月26日正式开启全平台公测。 该游戏在2021年10月27日曾开启过“始发测试”&#xff0c;后继续沉淀了两年才正式开启公测。 B站的ACG内容生态丰富&#xff0c;其中游戏相关内容当数米哈…

C++“this”指针的使用

1.this指针的引出 先看一段代码&#xff1a; class Date { public:Date(int year0,int month0,int day0){_year year;_month month;_day day;}void Print(){cout << _year << " "<< _month << " "<< _day << end…

无需公网IP 使用SSH远程连接Linux CentOS服务器【内网穿透】

文章目录 视频教程1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 本次教程我们来实现如何在外公网环境下&#xff0c;SSH远程连接家里/公司的Linux CentOS服务器&#xff0c;无需公网IP&#xff0c;也不需要设置…

SDK_examples问题汇总

CompParameter 看起来可以用 拖动中间的dialog框 调整下面的参数 GraphicsViewDropEvent 点击“模型库”或者“用户模型”会弹出如下&#xff0c;点击“中止”后退出页面 MassSpringDamperApp 成功过&#xff0c;现在点击“开始仿真”会显示仿真失败 MwBatchSimPlu…

Coremail RSAC大会观察:在邮件安全领域AI既是矛也是盾

《Coremail RSAC大会观察&#xff1a;在邮件安全领域AI既是矛也是盾》 全球网络安全界的盛会——2023年RSAC大会于当地时间4月24日-27日在美国旧金山召开&#xff0c;大会以“Stronger Together&#xff08;一起变得更强大&#xff09;”为主题&#xff0c;议程主要包含安全研…

想入门网络安全?先来看看网络安全行业人才需求!

如果你是一个想要入门网络安全行业的小白、如果你是网络安全专业在读的大学生、如果你是正在找工作的新手&#xff0c;那么这篇文章你一定要仔细看。毕竟知己知彼百战百胜&#xff0c;知道行业的人才需求才能更好得发挥自己的优势。 当你打开BOSS直聘、拉钩等招聘网站&#xf…

【CTF WriteUp】2023数字中国创新大赛网络数据安全赛道决赛WP(1)

2023数字中国创新大赛网络数据安全赛道决赛WP(1) 比赛感想 不多说了&#xff0c;还是菜&#xff0c;各种不会&#xff0c;还得学 数据安全题目 Crypto-ddddmm import os from Crypto.Util.number import * from secret import flagdef genkey(bits):p getPrime(bits)q g…