Spring复杂对象的3中创建方法

复杂对象是相对于简单对象可以直接 new 出的对象。这种对象在 Spring 中不可以通过简单对象的创建方式来创建。下面我们将通过实现 FactoryBean 接口、实例工厂、静态工厂三种方法来创建。

FactoryBean 接口

Spring 提供 FactoryBean 接口并且提供了 getObject 方法是为了支持自定义工厂。通过实现这个和接口,可以在获取 Bean 的时候执行一些定制化的操作,如返回一个特定的实例,或者根据特定条件来决定为 singleton 或者 prototype 类型。

getObject 方法允许自定义 Bean 创建过程,可以在这力编写自己的逻辑来决定返回的对象。并且在 getObjectType 方法中设定返回对象的类型。

注意:在实现这个接口的时候在后面指定的泛型是在配置文件中获取的对象类型,而不是实现接口的类对象。

代码演示:

ConnectionFactoryBean implements FactoryBean<Connection> :

注: isSingleton() 设定返回对象是否为单例模式

package com.day2springInject.factorybean;import org.springframework.beans.factory.FactoryBean;import java.sql.Connection;
import java.sql.DriverManager;public class ConnectionFactoryBean implements FactoryBean<Connection> {private String driverClassName;private String url;private String username;private String password;@Overridepublic Connection getObject() throws Exception {Class.forName(driverClassName);Connection conn = DriverManager.getConnection(url,username,password);return conn;}@Overridepublic Class<?> getObjectType() {return Connection.class;}@Overridepublic boolean isSingleton() {return false;}public String getDriverClassName() {return driverClassName;}public void setDriverClassName(String driverClassName) {this.driverClassName = driverClassName;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}

applicaitonContext.xml :

<!--    数据库连接。复杂对象的创建这里的对象是实现类的对象而不是调用类的     --><bean id="conn" class="com.day2springInject.factorybean.ConnectionFactoryBean"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property><property name="url" value="jdbc:mysql://localhost:3306/mp"></property><property name="username" value="root"></property><property name="password" value="123456"></property></bean>

TestSpring:

    @Testpublic void test12() {ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");Connection conn = (Connection) ctx.getBean("conn");  //  得到的是 Connection 对象Connection conn2 = (Connection) ctx.getBean("conn"); // 测试 isSingletonSystem.out.println(conn);System.out.println(conn2);}

运行截图: 

如果想要获取到原类的对象需要在getBean中加上 &

    @Testpublic void test13() {ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");ConnectionFactoryBean conn = (ConnectionFactoryBean) ctx.getBean("&conn");  // 这样获得的不是实现类对象了 而是调用类对象System.out.println(conn);}

 

 实例工厂

实例工厂是为了解决

整合遗留系统:在之前的项目中没有使用 Spring 的项目使用最常规的 new 的方式来实现,需要修改成 Spring 项目但是无法修改源码的情况下,我们只能通过添加配置的方法了实现。

避免 Spring 框架的耦合:

代码耦合度越低越好,但是这样创建项目会使返回对象类型依赖于创建类,所以我们要解除这种耦合。

原来的 Connction 类:

public class ConnectionFactory {public Connection getConnection() {Connection conn = null;try {Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mp","root","123456");} catch (ClassNotFoundException e) {throw new RuntimeException(e);} catch (SQLException e) {e.printStackTrace();}return conn;}
}

我们一看便知,这种创建放法在不让改变代码的前提下变成 Spring 项目并添加对象依赖,只能通过添加依赖的方法,我们需要操作如下两步:

1.添加 Connection 的依赖

我们想要获取连接对象必须先获取到他的类才可以进行下去,所以先将 Connction 注册进去。

<bean id="connFactory" class="com.day2springInject.factorybean.ConnectionFactory"/>

但是这样有问题存在,就是连接对象是依赖于 Connection 的,这样不就和 Spring 降耦合的理念违背了?而且使用效果不好,所以我们还需要将这个连接对象创建出来也就是 conn 对象。

<bean id="conn1" factory-bean="connFactory" factory-method="getConnection"></bean>

这里的 factory-bean 是将 “connFactory” 这恶鬼bean作为工厂来创建 conn1 这个对象,factory-method 指定了工厂方法,也就是说通过 connFactory 这个对象的 getConnection 方法来创建 conn1。

    @Testpublic void test14() {ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");Connection conn = (Connection) ctx.getBean("conn1");System.out.println(conn);}

 

静态工厂

静态工厂是为了创建静态方法中的返回对象的工厂,因为静态方法的调用相对于实例方法可以省略创建的一步,也就是直接通过类对象.方法来使用,也就是staticConnextionFactort.getConnection() 。如果在不修改代码的前提下想要变为 Spring 管理,也是只能通过添加配置的方式来注册。

<bean id="conn2" class="com.day2springInject.factorybean.StaticConnectionFactory" factory-method="getConnection"></bean>

可能你会好奇,都是创建对象,为什么静态工厂好像再还没创建出实例来就可以获取类的类型了。

应该可以这么理解,就是说在<bean>注册的时候,如果还没注册完成也就是没有到</bean>的时候是没有注册出对象的,而是获取到了Class类。所以这也就是实例对象为什么需要两步的原因,而静态对象少一步的原因。

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

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

相关文章

“熊猫杯” | 赛宁网安获网络安全优秀创新成果大赛优胜奖

9月11日&#xff0c;四川省2023年国家网络安全宣传周正式启动。由四川省委网信办指导&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;主办&#xff0c;成都信息工程大学、四川省网络空间安全协会承办的“2023年网络安全优秀创新成果大赛—成都分站赛(暨四川省‘…

Spring Boot - 用JUnit 5构建完美的Spring Boot测试套件

文章目录 PreJUnit 4 vs JUnit 5Junit5 常用注解栗子 Pre SpringBoot - 单元测试利器Mockito入门 SpringBoot - 应用程序测试方案 SpringBoot - SpringBootTest加速单元测试的小窍门 Spring Boot - Junit4 / Junit5 / Spring Boot / IDEA 关系梳理 package org.junit.jupit…

Excel VBA 变量,数据类型常量

几乎所有计算机程序中都使用变量&#xff0c;VBA 也不例外。 在过程开始时声明变量是一个好习惯。 这不是必需的&#xff0c;但有助于识别内容的性质&#xff08;文本&#xff0c;​​数据&#xff0c;数字等&#xff09; 在本教程中&#xff0c;您将学习- 一、VBA变量 变量是…

Unity中程序集dll

一&#xff1a;前言 一个程序集由一个或多个文件组成&#xff0c;通常为扩展名.exe和.dll的文件称为程序集&#xff0c;.exe是静态的程序集&#xff0c;可以在.net下直接运行加载&#xff0c;因为exe中有一个main函数(入口函数&#xff09;&#xff0c;.dll是动态链接库&#…

腾讯mini项目-【指标监控服务重构】2023-08-04

今日已办 关于 span-references 的调研 https://github.com/DataDog/dd-trace-js/issues/1761 https://github.com/open-telemetry/opentelemetry-specification/blob/874a451e7f6ac7fc54423ee3f03e5394197be35b/specification/compatibility/opentracing.md#span-references h…

基于springboot的OA人事办公管理系统

经典 oasys(OA自动化办公系统) 办公自动化&#xff08;OA&#xff09;是面向组织的日常运作和管理,员工及管理者使用频率最高的应用系统&#xff0c;极大提高公司的办公效率。 项目介绍 oasys是一个OA办公自动化系统&#xff0c;使用Maven进行项目管理。基于springboot框架开…

为什么要使用设计模式,以及使用设计模式的好处

在软件开发中&#xff0c;衡量软件质量只要包含如下指标&#xff1a; 正确性可维护性可读性可扩展性简洁性可测试性健壮性灵活性可复用性 然而&#xff0c;对于一些刚入行的新程序员来说&#xff0c;往往会注意不到上面这些问题&#xff0c;从而产生了一些让人头皮发麻的烂代…

谷粒商城----rabbitmq

一、 为什么要用 MQ? 三大好处&#xff0c;削峰&#xff0c;解耦&#xff0c;异步。 削峰 比如秒杀&#xff0c;或者高铁抢票&#xff0c;请求在某些时间点实在是太多了&#xff0c;服务器处理不过来&#xff0c;可以把请求放到 MQ 里面缓冲一下&#xff0c;把一秒内收到的…

Unity中Shader抓取屏幕并实现扭曲效果

文章目录 前言一、屏幕抓取&#xff0c;在上一篇文章已经写了二、实现抓取后的屏幕扭曲实现思路&#xff1a;1、屏幕扭曲要借助传入 UV 贴图进行扭曲2、传入贴图后在顶点着色器的输入参数处&#xff0c;传入一个 float2 uv : TEXCOORD&#xff0c;用于之后对扭曲贴图进行采样3、…

写一篇nginx配置指南

nginx.conf配置 找到Nginx的安装目录下的nginx.conf文件&#xff0c;该文件负责Nginx的基础功能配置。 配置文件概述 Nginx的主配置文件(conf/nginx.conf)按以下结构组织&#xff1a; 配置块功能描述全局块与Nginx运行相关的全局设置events块与网络连接有关的设置http块代理…

计算机网络(二):TCP篇

文章目录 1. TCP头部包含哪些内容&#xff1f;2. 为什么需要 TCP 协议&#xff1f; TCP 工作在哪一层&#xff1f;3. 什么是 TCP &#xff1f;4. 什么是 TCP 连接&#xff1f;5. 如何唯一确定一个 TCP 连接呢&#xff1f;6. UDP头部大小是多少&#xff1f;包含哪些内容&#xf…

burp+IE 微信小程序抓包教程

文章目录 一、BURP里新增监听端口二、BURP导出证书三、导入证书四、IE代理设置五、小程序抓包实际测试 一、BURP里新增监听端口 找一个没用的端口&#xff0c;使用以下方式新增 二、BURP导出证书 选择刚才新增的监听端口&#xff0c;点击证书导入导出 将其存出来即可&…

安卓机型系统美化 Color.xml文件必备常识 自定义颜色资源

color.xml文件是Android工程中用来进行颜色资源管理的文件.可以在color.xml文件中通过<color>标签来定义颜色资源.我们在布局文件中、代码中、style定义中或者其他资源文件中&#xff0c;都可以引用之前在color.xml文件中定义的颜色资源。 将color.xml文件拷到res/value…

c++的库函数std::move() 与 完美转发函数 std:: forward 源码

以下是两个注释&#xff1a; &#xff08;2&#xff09;以下是一个实验&#xff1a;

esxi网卡直通后虚拟机无网

出现选网卡的时候无法选中&#xff0c;这里应该是一个bug。 解决方法如下&#xff1a; 1.先随便选择一个网卡 2.勾先取消再重新勾选 3.保存退出&#xff0c;重启虚拟机即可

浅谈一下前端字符编码

背景 众所周知&#xff0c;计算机只能识别二进制&#xff0c;它是由逻辑电路组成&#xff0c;逻辑电路通常只有两个状态&#xff0c;开关的接通与断开&#xff0c;这两种状态正好可以用二进制数的0和1表示。但是现实中存在着其他的字符&#xff1a;数字、字母、中文、特殊符号…

学习记忆——数学篇——顺口溜记忆法+谐音记忆法+其他

顺口溜记忆法 【训练】 一次绝对不等式的解集&#xff1a;不等式| x x x| &#xff1e; a ( a > 0 ) &#xff1e;a(a>0) &#xff1e;a(a>0)的解集是 X > a 或 X < − a X>a或X<-a X>a或X<−a&#xff0c;不等式| x x x| < a ( a > 0 ) <…

Java————数组

1 、数组 数组可以看成是相同类型元素的一个集合&#xff0c; 在内存中是一段连续的空间。 每个空间有自己的编号&#xff0c;其实位置的编号为0&#xff0c;即数组的下标。 数组是引用类型。 1. 数组的创建 T[] 数组名 new T[N];T&#xff1a;表示数组中存放元素的类型 …

苹果官网数秒就被抢购引发崩溃,iPhone15热销,对小丑的强烈讽刺

面对网络上对iPhone15恶评如潮&#xff0c;甚至还有假5G等的风波&#xff0c;然而iPhone15的预购却超乎寻常的热烈&#xff0c;以至于苹果官网在开售几秒内就已崩溃了&#xff0c;显示出今年的iPhone15销售情况恐怕比往年的更要好。 除了苹果官网被抢购到崩溃之外&#xff0c;几…