Spring之详解bean的实例化

目录
  • bean实例化
    • bean的基础配置
    • bean的实例化-构造方法
    • bean的实例化-静态工厂
    • bean的实例化-实例工厂与FactoryBean
  • 总结

bean实例化

bean的基础配置

在学习bean的实例化之前,我们先来学习bean该如何配置。

在bean的配置这一块,我们将学习三块内容,分别为:我们先来看一下bean的基础配置bean基础配置、bean别名配置、bean作用范围配置。

id用来定义bean的名称,通过它可以获取,class用来指定bean的类型,也就是你造出来的bean究竟是哪一个类的

那么这个时候就有一个问题了,对应的bean的id你写好了,但是你的命名习惯和我的命名习惯不一样,我不想叫这个名称,有没有办法呢,这就是有关bean可以起多个名称,也就是所谓的bean的别名。

  • 接下来我们来看bean的别名配置,在学习之前,我们先来交代一下当前的程序环境

service层接口

service层实现类

dao层接口

dao层实现类

applicationContext.xml配置文件

主方法

  • 在了解了程序环境以后,我们开始来学习别名配置。

我们知道bean的别名肯定是写在applicationContext.xml配置文件中的 ,怎么写呢,在配置的 bean中,有一个name属性,可以为这个bean指定更多的名称。

注意:别名可以有多个,使用逗号,分号,或者空格进行分隔。

当我们在主方法中将getBean()方法里边的参数改为我们配置的别名,我们会发现程序还可以正常运行,那就说明我们配置的别名是有效的。

接下来我们思考:我们在绑定service与dao的关系时,在service层配置的bean里边有一个属性ref表示的是参照dao层配置的bean,属性值为dao层配置的bean的属性id,那么如果我们将ref这个属性改为我们在dao层配置的bean的别名,那么程序还可以正常运行吗?我们来演示一下

通过以上演示,我们可以得知别名的作用范围是很大的虽然我们学习了用别名配置bean的方式,但是还是建议我们ref参照的时候,还是引用id属性。

  • 接下来需要说一说我们需要注意的问题了

回到我们的主方法中,我们现在在getBean()方法中传递进去一个我们没有的参数service5,这是在配置的service的bean中的id属性和name属性都没有的参数,那我们运行的话会有什么问题呢

运行完会报出一个异常,这个异常的意思就是没有一个这样的bean被定义,如果以后我们遇到这个异常的话,只需要检查我们的名字就行了

  • bean的别名配置我们已经说完了,接下来我们来学习bean的作用范围

什么叫bean的作用范围呢?其实就是你现在创建的bean的究竟是一个对象还是多个对象,什么意思呢,其实就是说你造的对象是单例的还是非单例的,我们先来看看如下代码

我们获取到BookDao的对象,并且打印它的地址

那我们将以上代码复制两份并且分别打印它们的地址,会出现什么结果呢

通过运行结果我们可以发现,两次打印的结果是同一个地址,那么它们也可以认为是同一个对象了

由此得出:Spring默认给我们创建的bean是单例的,那么这时候就有新问题了,如果我想要创建一个非单例的该怎么办,这个时候就要通过配置的方法解决这个问题了

如下,我们在dao层配置的bean后边再加一个属性scope,就是作用范围的意思

里边有两个值,一个singleton表示单例的,一个prototype表示非单例的,不写的话,默认是signleton,我们设置scope属性为prototype,来看看运行结果

通过运行结果我们可以得出,此时的所创建的两个对象是不同的,注意:我们上面所框出的是对象的哈希值,不是对象的地址但是可以当做是对象的地址

  • 在学完bean的作用范围,我们可以认为它是可以控制创建的bean是一个或者是多个的,那么新的问题来了,为什么bean默认是单例的

我们来解释一下,对于Spring来说,它帮我们管理的bean要放到它的容器中,我们 假定一个场景,如果它造出来的bean不是非单例的,那么这个bean的数量会有多少呢?

它会无穷无尽,用一次造一个,所以说Spring它并不是帮我们管理这一类bean的

这样的话,对Spring容器来说也有一个非常大的压力,那Spring帮我们管理的bean都是单例的,那会对我们的业务造成伤害吗

你想一想,你造一个dao对象,执行完一个方法,下一次你又需要造一个dao对象,再执行另一个方法,那我这两个对象用同一个不行吗?

好像没有什么问题,就是这个原因,Spring容器在帮我们管理对象的时候其实就是在管理那些你可以复用的对象,就是这个对象你用一次,下一次还用它,所以你下次还会从容器中拿,这样它的效率才会更高一些,

因此,它就简单一点,给你造的bean就是单例的。

  • 那么新的问题有又来了,哪些bean适合造单例的呢

我们的表现层对象,比如说我们现在写的Servlet,业务层对象, Service,数据层对象,Dao,或者还有一些工具类的对象,这些对象,你造一次就ok了,就这个对象我可以反复用,这些东西交给Spring管理。

  • 那哪些东西不适合交给Spring管理呢

封装实体的域对象不适合交给Spring管理,因为它里边会记录一些它的成员变量的一些属性值,到这里我们就知道了bean的作用范围是控制我们bean创建的实例的数量的。

bean的实例化-构造方法

上面我们学习完了bean的基础配置,那就有人问了,我们的这个单例bean是如何造出来的呢,和我们以前的写法一样吗,也是用new的方式造出来的吗,我们现在就来学习bean的实例化-构造方法实例化的方式。

对于bean来说,其本质是对象,在前面我们说过,我们将容器中管理的对象叫做bean,我们以前创造对象是怎么写:new跟构造方法,对于Spring来说,它也是通过构造方法来完成bean的创建的,一起来看一下

以上是我们程序的环境️️,接下来我们来说以前我们造对象new+构造方法,对于Spring来说,同样的道理,它也是用构造方法来造对象的。

接下来我们在dao的实现类中生成构造方法,并且在构造方法中打印一句话

什么都不动,我们再来运行一下,看看这句话执行了没有,如果执行了,那就意味着Spring容器调用了构造方法造对象

结果是用了,造对象都得用构造方法,在这说一个东西,我们将构造方法的权限修饰符改为private,我们说如果以前我们写程序,把构造方法私有化以后,我们在外边还可以造对象吗?显然是绝对造不出来的

结果是不是出人意料啊,Spring还可以调用它的构造方法

那就说明了一点,Spring确实是通过构造方法来造对象的,而且不管是公共的还是私有的它都能调到,我们可以猜到它的内部是怎么回事吗,私有的东西它居然可以访问,怎么做的

是通过反射,后边我们在学习一些内部工作原理的时候,我们再来学习它,现在只需要知道它是通过构造方法造对象的就可以了

但是这个时候就有人提出来了一个问题,那万一给它加一个参数呢?

我们来试一试,并且运行一下,会发现它已经不能正常运行了,这就说明了一点,Spring在创建bean的时候,调用的是无参构造方法,到这里我们就学习完了第一种实例化bean的方式,就是用构造方法来实例化对象

bean的实例化-静态工厂

  • 前面我们学习了用构造方法来实例化bean,接下来我们来说第二种方式,在学习第二种方式之前
  • 我们先来回顾一个东西,我们在前边讲过,用工厂也可以造对象,我们先来看看程序环境

  • 接下来我提供了一个工厂类

  • 如果用这个来写的话,会是什么样子的呢?接下来我们来看一下

先去使用工厂去获得这个对象,然后去运行,我们去运行一下

我们发现这是可以运行的,其实这是早些年做程序的一个常用的方式,说的简单一点就是造对象不要自己new,而是用工厂的方式做一定程度的解耦,那么这种方式也是造对象的一种方式

如果我们的对象是用这样一种方式造出来的,交给Spring管理该怎么管呢?

这就是我们要学习的第二种方式:用静态工厂来造对象,接下来我们来学习以下该怎么做

对于它的接口实现类和静态工厂来说,这三个东西是一套东西

如果我们现在要管理这个bean,首先要写它的配置文件,那么问题来了,这样造出来的对象究竟是dao的对象还是factory的对象应该是factory的

因为你配什么造出来的就是什么,那我们要的是factory的对象吗?

显然不是,我们要的是factory里边的方法造出来的dao对象,所以我们下面这么写肯定是不行的,我们除了要告诉它的工厂类,还要告诉它一个东西factory-method属性来告诉它工厂是使用哪一个方法来造对象的,到这就可以造出来了,我们来运行一下,当然是用Spring的方式来运行的。

到这我们的第二种方式就学完了,但是还有一个问题,为什么不直接new啊,我们要知道工厂中做的有事情,可能会有一些配置,并且不能扔,所以强制你必须要用这个工厂,我们再来运行一下

bean的实例化-实例工厂与FactoryBean

接下来我们来学习第三种方式,首先我们来看看程序环境。

注意:此时这个工厂是非静态的。

在了解完程序环境后,我们就开始学习它

首先也是一样打开配置文件,我们在实例化的时候,必须先去造一个实例工厂类的对象,所以我们先来配置实例工厂类的bean

我们在造出这个工厂类的对象以后,我们再来配置dao层的bean,属性factory-bean指的是这个工厂的实例在哪呢,第二个是这个工厂用哪个方法来造这个对象的。

我们来用Spring的方式来运行一下

上边我们为了造dao层的对象,专门写了一个factory的bean,其实这个东西挺多余的,除了这个作用以外,无任何意义,还有在dao层的bean里边有一个属性factory-method,方法名不固定,每个里边都得指定,那么这种东西不能写一个通用的名称吗?

针对以上问题,Spring就做了一次改良:FactoryBean,我们先来看看程序环境

  • 注意:工厂造什么对象,就写什么泛型,第二个方法返回的是对象的字节码文件.

我们可能会发现,它和上边的好像没什么区别,但是它在配置的时候可简单多了,我们接下来在配置文件中配bean,并且看看是否可以正常运行

结果是可以正常运行,这就是我们所说的第三种方式的改良了,在这里我们覆盖了一个方法isSingleton

那接下来我们来看看,既然你造出来这个对象了,我们可以想一想,造出来的这个对象是单例的还是非单例,我们来通过getBean()方法获得两个userDao对象,并且分别打印,接下来我们来看一下

我们通过结果可以看出,通过这种方式造出来的对象是单例的,那么怎么样去改非单例的呢,我们在UserDaoFactoryBean中加上isSingleton方法,然后返回值设置为false,就可以改成非单例的了

我们再来运行一下,此时就变成非单例的了

总结

在本篇文章中,我们先来介绍了bean的基础配置,然后详细介绍了几种实例化bean的方式.

到此这篇关于Spring之详解bean的实例化的文章就介绍到这了,更多相关Spring之bean的实例化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 在spring中实例化bean无效的问题

    目录 spring中实例化bean无效 Action中代码如下 applicationContext.xml中配置如下 spring实例化bean顺序问题,导致注入失败 问题如下 原因 解决 spring中实例化bean无效 在做Struts2和Spring整合时遇到Spring实例化无效的情况, Action中代码如下 public class UserAction extends ActionSupport {     @Resource     private UserService us

  • Spring实例化bean的四种方式详解

    目录 一.bean实例化——构造方法(常用) 二.bean实例化——静态工厂(了解) 三.bean实例化——实例工厂(了解) 四.bean实例化——FactoryBean(实用) 一.bean实例化——构造方法(常用) bean本质上就是对象,创建bean使用构造方法完成 BookDao接口: public interface BookDao { public void save(); } BookDaoImpl实现类,利用构造方式提供可访问的构造方法,输出相应字符串: import com.i

  • SpringBoot借助spring.factories文件跨模块实例化Bean

    目录 1. 前言 2. 配置 3. 原理 4. 总结 1. 前言 SpringBoot在包扫描时,并不会扫描子模块下的内容,这样就使得我们的子模块中的Bean无法注入到Spring容器中.SpringBoot就为我们提供了spring.factories这个文件,让我们可以轻松的将子模块的Bean注入到我们的Spring容器中,本篇文章我们就一起探究一下spring.factories 跨模块实例化Bean的原理. 我们在上篇文章中也讲到构建自己构建starter,其中spring.factor

  • Bean实例化之前修改BeanDefinition示例详解

    目录 BeanFactory 通过BeanDefinition对象实例化Bean对象 BeanFactory BeanFactory是Spring中容器功能的基础,用于存放所有已经加载的bean,为了保证程序上的高可扩展性,Spring针对BeanFactory做了大量的扩展.BeanFactoryPostProcessor是BeanFactory的后置处理器:比如在postProcessBeanFactory方法中,可以获取BeanDefinition的相关对象,并且修改该对象的属性. @Fu

  • Spring Bean生命周期之Bean的实例化详解

    目录 前言 实例化前阶段 实例化阶段 实例化后阶段 总结 前言 上一节说到了BeanDefinition的合并过程,这节该说Bean的实例化过程了.根据AbstractAutowireCapableBeanFactory#createBean源码逻辑 可将实例化过程分为实例化前阶段.实例化过程.实例化后阶段. 实例化前阶段 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[]

  • Spring中Bean的三种实例化方式详解

    目录 一.环境准备 二.构造方法实例化 三.分析Spring的错误信息 四.静态工厂实例化 4.1 工厂方式创建bean 4.2 静态工厂实例化 五.实例工厂与FactoryBean 5.1 环境准备 5.2 实例工厂实例化 5.3 FactoryBean的使用 六.bean实例化小结 一.环境准备 准备开发环境 创建一个Maven项目 pom.xml添加依赖 resources下添加spring的配置文件applicationContext.xml 最终项目的结构如下: 二.构造方法实例化 在

  • IOC 容器启动和Bean实例化两个阶段详解

    目录 IOC 容器的两个阶段 容器启动阶段 Bean 实例化阶段 插手容器的启动 PropertyPlaceholderConfigurer 占位符机制 PropertyOverrideConfigurer 重写属性值 实例-使用容器扩展点修改 BeanDefinition IOC 容器的两个阶段 IOC 容器可以分为两个阶段 : 容器启动阶段和 Bean 实例化阶段. Spring 的 IoC 容器在实现的时候, 充分运用了这两个阶段的不同特点, 在每个阶段都加入了相应的容器扩展点, 支持开发

  • 详解Spring Bean的配置方式与实例化

    目录 一. Spring Bean 配置方式 配置文件开发 注解开发 二.Spring Bean实例化 环境准备 构造方法实例化Bean 静态工厂实例化Bean 实例工厂实例化Bean FactoryBean 一. Spring Bean 配置方式 由 Spring IoC 容器管理的对象称为 Bean,Bean 配置方式有两种:配置文件开发和注解开发 配置文件开发 Spring 配置文件支持两种格式:xml和properties,此教程以xml配置文件讲解. XML 配置文件的根元素是 <be

  • 基于springboot bean的实例化过程和属性注入过程

    目录 bean的实例化过程和属性注入过程 bean实例化流程说明 bean的实例化过程和属性注入过程 了解过springboot的加载流程的都知道springboot初始化bean都在refresh方法中. 这个方法代码如下: // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory.新建beanFactory Config

  • Java Spring框架简介与Spring IOC详解

    目录 Spring简介和配置 1.Spring概述 1.1 spring 是什么 1.2 Spring发展历程 1.3 Spring的优势 (理解) \1. 方便解耦,简化开发 \2. AOP 编程的支持 \3. 声明式事务的支持 \4. 方便程序的测试 \5. 方便集成各种优秀框架 \6. 降低 JavaEE API 的使用难度 \7. Java 源码是经典学习范例 1.4 Spring的体系结构(了解) 2.Spring IoC快速入门 2.1 IoC的概念和作用 2.2 Spring Io

  • JSP 开发之Spring Security详解

    JSP 开发之Spring Security详解 前言: spring Security是一个能够为基于Spring的企业应用系统提供描述性安全访问控制解决方案的安全框架.它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(依赖注入,也称控制反转)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复代码的工作. Spring Security 的前身是 Acegi Security ,是 Spring 项

  • Spring Boot详解五种实现跨域的方式

    目录 一.为什么会出现跨域问题 二.什么是跨域 三.非同源限制 四.java后端实现CORS跨域请求的方式 1. 返回新的CorsFilter(全局跨域) 2. 重写WebMvcConfigurer(全局跨域) 3. 使用注解 (局部跨域) 4. 手动设置响应头(局部跨域) 5. 使用自定义filter实现跨域 一.为什么会出现跨域问题 出于浏览器的同源策略限制.同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能

  • Spring boot详解缓存redis实现定时过期方法

    目录 前言 添加依赖 添加配置 常规缓存 开启缓存 设置缓存空间 设置缓存 增加设置缓存过期时间 总结 后记 前言 使用redis进行缓存数据,是目前比较常用的缓存解决方案.常用的缓存形式有一下几种: 1.纯原生代码进行redis的增删改查,手工编写缓存工具类,由开发者在代码中进行调用. 优势:代码由实际使用的开发者进行维护,便于定制化的改造. 2.使用市场上已有的缓存工具,也就是大家常说的大佬的轮子 优势:方便快捷,提升开发效率 添加依赖 修改pom文件引入如下配置 <?xml version

  • MyBatis集成Spring流程详解

    目录 一.Mybatis与spring集成 1. 导入pom依赖 2. 编写配置文件 3. 使用注解开发 4. 测试 5. 管理数据源 二.Aop整合pagehelper插件 要解决的问题 一.Mybatis与spring集成 1. 导入pom依赖 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8

  • Spring Boot详解创建和运行基础流程

    目录 1. 初始 Spring Boot 1.1 什么是Spring Boot 1.2 Spring Boot 的优点 2. 创建 Spring Boot 项目(Idea) 2.1 首先安装 Spring Assistant 插件 2.2 重启Idea-New Project ① 点击 Spring Assistant 直接Next就可以了 ② Next 之后的页面介绍 ③ 引入依赖, 选择Spring Boot的版本 ④ 选择项目名称和保存路径 ⑤ Spring Boot 项目创建完成 3.

  • Spring Boot详解配置文件的用途与用法

    目录 1. SpringBoot 配置文件 1.1 配置文件的作用 1.2 配置文件的格式 1.3 properties 配置文件说明 1.3.1 properties 基本语法 1.3.2 读取配置文件 1.4 yml 配置文件说明 1.4.1 yml 基本语法 1.4.2 yml 使用进阶 1.4.3 配置对象 1.4.4 配置集合 1.4.5 yml的另一种写法(行内写法) 1.5 properties 和 yml 比较 2. 读取 SpringBoot 配置文件的方法 2.1 使用 @V

  • Spring源码解析 Bean的实例化

    目录 前言 准备工作 实例化bean 1.AbstractBeanFactory 的 doGetBean方法 2.AbstractAutowireCapableBeanFactory 的 createBean方法 3.AbstractAutowireCapableBeanFactory 的 doCreateBean方法 4.AbstractAutowireCapableBeanFactory 的 createBeanInstance方法 5.AbstractAutowireCapableBean

  • Spring AOP详解面向切面编程思想

    目录 1. 什么是 Spring AOP 2. AOP 的组成 2.1 切面 (Aspect) 2.2 切点 (Pointcur) 2.3 连接点 (Join Point) 2.4 通知 (Advice) 3. Spring AOP 的使用 3.1 添加 AOP 框架 3.2 定义切面和切点 3.3 定义通知 (五种) 4. Spring AOP 实现原理 4.1 织入 (Weaving) 4.2 JDK 和 CGLIB 实现的区别 1. 什么是 Spring AOP AOP (Aspect O

  • Spring Boot详解整合JWT教程

    目录 1.概述 2.优势所在 3.结构组成 3.1.标头(Header) 3.2.有效负载(Payload) 3.3.签名(Signature) 4.Spring boot整合JWT 导入依赖 1.概述 JWT 简称 JSON Web Token,也就是通过JSON形式作为Web应用中的令牌,用于各方之间安全地将信息作为JSON对象传输,在数据传输的过程中还可以完成数据加密.签名等相关处理. 2.优势所在 在JavaWeb阶段,经常使用session来存储,以方便用来判断用户是否操作等等.但这又

随机推荐

其他