【spring】第二篇 bean实例化
对象已经能交给Spring的IOC容器来创建了,但是容器是如何来创建对象的呢?
就需要研究下
bean的实例化过程,在这块内容中主要解决两部分内容,分别是
bean是如何创建的
实例化bean的三种方式,
构造方法,静态工厂和实例工厂在讲解这三种创建方式之前,我们需要先确认一件事:bean本质上就是对象,对象在new的时候会使用构造方法完成,那创建bean也是使用构造方法完成的。
基于这个知识点出发,我们来验证spring中bean的三种创建方式。

目录
一、构造方法实例化
优化
二、静态工厂实例化
使用工厂来创建对象
优化
三、实例工厂实例化
优化:FactoryBean使用
小结
一、构造方法实例化
优化
(1)准备需要被创建的类
准备一个BookDao和BookDaoImpl类,
package com.water.dao;public interface BookDao {public void save();
}
在BookDaoImpl类中添加一个无参构造函数,并打印一句话,方便观察结果。
package com.water.dao.impl;import com.water.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 ...");}
}
(2)将类配置到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标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型--><bean id="bookDao" class="com.water.dao.impl.BookDaoImpl"></bean>
</beans>
(3)运行程序,如果控制台有打印构造函数中的输出,说明Spring容器在创建对象的时候也走的是构造函数

(4)将构造函数改成private测试

运行程序,能执行成功,

说明内部走的依然是构造函数,能访问到类中的私有构造方法,显而易见Spring底层用的是反射。
(5)构造函数中添加一个参数测试

运行程序,程序会报错,说明Spring底层使用的是类的无参构造方法。

接下来,我们主要研究下Spring的报错信息,来学一学如阅读。
-
错误信息从下往上依次查看,因为上面的错误大都是对下面错误的一个包装,最核心错误是在最下面
-
Caused by: java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.
<init>()-
Caused by 翻译为
引起,即出现错误的原因 -
java.lang.NoSuchMethodException:抛出的异常为
没有这样的方法异常 -
com.itheima.dao.impl.BookDaoImpl.
<init>():哪个类的哪个方法没有被找到导致的异常,<init>()指定是类的构造方法,即该类的无参构造方法
-
如果最后一行错误获取不到错误信息,接下来查看第二层:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.<init>()
-
nested:嵌套的意思,后面的异常内容和最底层的异常是一致的
-
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found;
-
Caused by:
引发 -
BeanInstantiationException:翻译为
bean实例化异常 -
No default constructor found:没有一个默认的构造函数被发现
-
看到这其实错误已经比较明显,
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bookDao' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.<init>()。
至此,关于Spring的构造方法实例化就已经学习完了,因为每一个类默认都会提供一个无参构造函数,所以其实真正在使用这种方式的时候,我们什么也不需要做。这也是我们以后比较常用的一种方式。
二、静态工厂实例化
使用工厂来创建对象
在讲这种方式之前,我们需要先回顾一个知识点是使用工厂来创建对象的方式:
- 准备一个OrderDao和OrderDaoImpl类
- 创建一个工厂类OrderDaoFactory并提供一个静态方法
- 编写AppForInstanceOrder运行类,在类中通过工厂获取对象
public interface OrderDao {public void save();
}public class OrderDaoImpl implements OrderDao {public void save() {System.out.println("order dao save ...");}
}
//静态工厂创建对象
public class OrderDaoFactory {public static OrderDao getOrderDao(){return new OrderDaoImpl();}
}
public class AppForInstanceOrder {public static void main(String[] args) {//通过静态工厂创建对象OrderDao orderDao = OrderDaoFactory.getOrderDao();orderDao.save();}
}
如果代码中对象是通过上面的这种方式来创建的,如何将其交给Spring来管理呢?
优化
这就要用到Spring中的静态工厂实例化的知识了,具体实现步骤为:
(1)在spring的配置文件application.properties中添加以下内容,
<?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标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型 工厂类的类全名factory-mehod:具体工厂类中创建对象的方法名--><bean id="orderDao" class="com.water.dao.factory.OrderDaoFactory" factory-method="getOrderDao"/>
</beans>

(3)在AppForInstanceOrder运行类,使用从IOC容器中获取bean的方法进行运行测试,
package com.water;import com.water.dao.BookDao;
import com.water.dao.OrderDao;
import com.water.dao.factory.OrderDaoFactory;
import com.water.server.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main( String[] args ) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");orderDao.save();}
}
运行后,可以查看到结果,

这样的好处就是,在工厂的静态方法中,我们除了new对象还可以做其他的一些业务操作,这些操作必不可少。
public class OrderDaoFactory {public static OrderDao getOrderDao(){System.out.println("factory setup....");//模拟必要的业务操作return new OrderDaoImpl();}
}
之前new对象的那种方式就无法添加其他的业务内容。
三、实例工厂实例化
package com.water.dao;public interface OrderDao {public void save();
}
package com.water.dao.impl;import com.water.dao.OrderDao;public class OrderDaoImpl implements OrderDao {public void save() {System.out.println("order dao save ...");}
}
package com.water;import com.water.dao.BookDao;
import com.water.dao.OrderDao;
import com.water.dao.factory.OrderDaoFactory;
import com.water.server.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main( String[] args ) {//创建实例工厂对象OrderDaoFactory OrderDaoFactory = new OrderDaoFactory();//通过实例工厂对象创建对象OrderDao OrderDao = OrderDaoFactory.getOrderDao();OrderDao.save();}
}

对于上面这种实例工厂的方式如何交给Spring管理呢?
优化:FactoryBean使用
(1)创建一个OrderDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
FactoryBean接口其实会有三个方法,分别是:
T getObject() throws Exception;Class<?> getObjectType();default boolean isSingleton() {return true; }方法一:getObject(),被重写后,在方法中进行对象的创建并返回
方法二:getObjectType(),被重写后,主要返回的是被创建类的Class对象
方法三:没有被重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默认true,单例。
package com.water.dao.factory;import com.water.dao.OrderDao;
import com.water.dao.impl.OrderDaoImpl;
import org.springframework.beans.factory.FactoryBean;public class OrderDaoFactoryBean implements FactoryBean<OrderDao> {@Overridepublic OrderDao getObject() throws Exception {return new OrderDaoImpl();}@Overridepublic Class<?> getObjectType() {return OrderDao.class;}public boolean isSingleton() {return false;}
}
(2)在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标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型 工厂类的类全名factory-mehod:具体工厂类中创建对象的方法名--><bean id="orderDao" class="com.water.dao.factory.OrderDaoFactoryBean"/>
</beans>
(3)运行类不用做任何修改,直接运行,
package com.water;import com.water.dao.BookDao;
import com.water.dao.OrderDao;
import com.water.dao.factory.OrderDaoFactory;
import com.water.server.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main( String[] args ) {//创建实例工厂对象ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");OrderDao orderDao1 = (OrderDao) ctx.getBean("orderDao");System.out.println(orderDao1);OrderDao orderDao2 = (OrderDao) ctx.getBean("orderDao");System.out.println(orderDao2);}
}

通过验证,会发现默认是单例,那如果想改成单例具体如何实现?只需要将isSingleton()方法进行重写,修改返回为false即可。
重新运行,查看结果,

从结果中可以看出现在已经是非单例了,但是一般情况下我们都会采用单例,也就是采用默认即可。所以isSingleton()方法一般不需要进行重写。
小结
通过这一节的学习,需要掌握:
(1)bean是如何创建的呢?
构造方法
(2)Spring的IOC实例化对象的三种方式分别是:
-
构造方法(常用)
-
静态工厂(了解)
-
实例工厂(了解)
-
FactoryBean(实用)
-
这些方式中,重点掌握构造方法和FactoryBean即可。
需要注意的一点是,构造方法在类中默认会提供,但是如果重写了构造方法,默认的就会消失,在使用的过程中需要注意,如果需要重写构造方法,最好把默认的构造方法也重写下。
相关文章:
【spring】第二篇 bean实例化
对象已经能交给Spring的IOC容器来创建了,但是容器是如何来创建对象的呢? 就需要研究下bean的实例化过程,在这块内容中主要解决两部分内容,分别是 bean是如何创建的 实例化bean的三种方式,构造方法,静态工厂和实例工厂 在讲解这…...
MVC和MVVM
MVC Model层:用于处理应用程序数据逻辑的部分,通常负责在数据库中存取数据 View(视图)处理数据显示的部分。通常视图是依据模型数据创建的 Controller(控制器)是处理用户交互的部分。通常控制器负责从视…...
【康耐视国产案例】智能AI相机机器视觉精准快速实现包裹标签的智能粘贴
康耐视推出的3D-A1000是专业的、匹配物流行业各类分拣机及包裹检测应用的全功能视觉检测系统,其能够准确检测分拣机上是否有包裹、包裹是否超出边界、空车检测、是否有遗留物品等。由于搭载了专利的三维结构光技术,产品具有更强大的创新性以满足持续更新…...
发现真正的诉求
在不久前,我在负责一个项目,设计了一个方案。但是,与我一同合作的同事对其中的一个设计点持有异议。我们尝试讨论解决,但似乎没有找到共识。然而,尽管双方的观点没有达成一致,我们都清楚地表达了自己的想法…...
Spring Boot配置MySQL数据库连接数
1.如何在Spring Boot中配置MySQL数据库的连接数 1.1主要配置 在Spring Boot中配置MySQL数据库连接数通常涉及到两个主要的配置: (1)数据源配置:这通常是在application.properties或application.yml文件中完成的,用于…...
springboot595基于Java的大学生迎新系统-手把手调试搭建
springboot595基于Java的大学生迎新系统-手把手调试搭建 springboot595基于Java的大学生迎新系统-手把手调试搭建...
20 道大模型面试问题(含答案)
大型语言模型在生成式人工智能(GenAI)和人工智能(AI)中正变得越来越有价值。这些复杂的算法增强了人类的能力,并在各个领域促进了效率和创造力。 节前,我们组织了一场算法岗技术&面试讨论会࿰…...
【Java面试】四、MySQL篇(上)
文章目录 1、定位慢查询2、慢查询的原因分析3、索引3.1 数据结构选用:二叉树 & 红黑树3.2 数据结构选用:B树 4、聚簇索引、非聚簇索引、回表查询4.1 聚簇索引、非聚簇索引4.2 回表查询 5、覆盖索引、超大分页优化5.1 覆盖索引5.2 超大分页处理 6、索…...
【Python】collections模块:高效处理数据的利器
Python中的collections模块:高效处理数据的利器 Python的collections模块是一个内置模块,它提供了一些专用的容器数据类型,作为Python通用内置容器(如列表list、字典dict、集合set和元组tuple)的替代品。本文将深入探…...
Vue3实战笔记(51)—Vue 3封装带均线的k线图
文章目录 前言带均线的k线图总结 前言 继续封装一个封装带均线的k线图 带均线的k线图 EChartsCandlestickSh.vue: <template><div ref"chartContainer" style"width: 100%; height: 500px"></div></template><scr…...
信息与未来2015真题笔记
[信息与未来 2015] 加数 题目描述 给出一个正整数 n n n,在 n n n 的右边加入 ⌊ n 2 ⌋ \left\lfloor\dfrac n2\right\rfloor ⌊2n⌋,然后在新数的右边 再加入 ⌊ ⌊ n 2 ⌋ 2 ⌋ \left\lfloor\dfrac{\left\lfloor\dfrac n2\right\rfloor}2\rig…...
【成功解决】Access token invalid or no longer valid
项目场景: python调用文心一言对应的ERNIE-4.0-8K模型API接口,方式为单次调用 问题描述 提示: “error_code”: 110, “error_msg”: “Access token invalid or no longer valid” C:\Users\PUB\AppData\Local\Programs\Python\Python38-…...
【Bug】修改计算机名称出现ip无法连接mysql数据库
解决: mysql -u root -p输入密码登录mysql服务器,那个ip是本机ip4的地址单ip放行。推荐全部,后面123456是密码 GRANT ALL PRIVILEGES ON *.* TO root192.168.0.109 IDENTIFIED BY 123456; 全部IP都放行 GRANT ALL PRIVILEGES ON *.* …...
米尔MYC-Y6ULX-V2开发板测评记录
文章目录 1、板子上手体验2、板载硬件3、系统信息4、 驱动测试5、编译linux三大件7、摄像头测试9、总结 1、板子上手体验 首先非常感谢芯查查给了这样一个机会来测评这样一款性能十分强大的开发板,我拿到手的是MYC-Y6ULX-V2核心板及开发板,这块板子具有…...
装修全流程
Summary 从2023年底到现在(2024年6月2日),装修可以定的东西基本过半了,我按照时间顺序把每个环节的内容和想法都记录一下 环节 选装修公司、找设计师设计环节预算计算角色介绍建材选型敲墙和开工水电放样泥工木工放样To be cont…...
探索微软Edge
微软开发的官方浏览器 Microsoft Edge是微软基于 Chromium 开源项目及其他开源软件开发的网页浏览器。 2015年4月30日,微软在旧金山举行的Build 2015开发者大会上宣布——Windows 10内置代号为“Project Spartan”的新浏览器被正式命名为“Microsoft Edge”&#x…...
Java面试——专业技能
优质博文:IT-BLOG-CN 一、简单讲下 Java 的跨平台原理 由于各个操作系统(Windows,Linux等)支持的指令集不是完全一致的。就会让我们程序在不同的操作系统上要执行不同的程序代码。Java 开发了适用于不同操作系统及位数的 Java 虚拟…...
C#按钮样式设置XMAL
统一按钮样式 <Window.Resources> <!--按钮样式统一设置,个别按钮单独定义样式的话则需要在定义按钮位置单独设置--><Style TargetType"Button"><Setter Property"Background" Value"Red"/><Setter Prop…...
EmmyLua注释详解
Lua EmmyLua 注解详解 Why 为了使 IDE 编码体验和强语言相近 让 IDE 提前发现编码错误 BUG 查找更方便 代码阅读更方便 建议 明确字段类型 明确字段访问修饰符 明确方法参数类型 善用 “:” 继承 “|” 或 ","多个 支持格式 –类 —class MY_TYPE[:PARENT_TYPE] [com…...
Linux内核 -- 启用 Linux 内核调试信息
启用 Linux 内核调试信息 本文档提供了如何在编译 Linux 内核时启用调试信息的逐步指南。调试信息对于调试和诊断内核问题至关重要。 启用调试信息的步骤 1. 进入内核源代码目录 打开终端并导航到 Linux 内核源代码目录: cd /path/to/linux-kernel2. 配置内核 …...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
