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

news2024/11/19 19:36:52

复杂对象是相对于简单对象可以直接 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;


    @Override
    public Connection getObject() throws Exception {
        Class.forName(driverClassName);
        Connection conn = DriverManager.getConnection(url,username,password);
        return conn;
    }

    @Override
    public Class<?> getObjectType() {
        return Connection.class;
    }

    @Override
    public 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:

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

运行截图: 

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

    @Test
    public 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。

    @Test
    public 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.coloradmin.cn/o/1017737.html

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

相关文章

【Vue.js】生命周期与基本使用

&#x1f3ac; 艳艳耶✌️&#xff1a;个人主页 &#x1f525; 个人专栏 &#xff1a;《Spring与Mybatis集成整合》 《springMvc使用》 ⛺️ 生活的理想&#xff0c;为了不断更新自己 ! 目录 ​编辑 1.Vue是什么 2.Vue的特点及优势 3. 使用Vue的详细步骤 3.1.导入 3.2…

Vue3引入滑块验证组件-2分钟搞定

安装 npm install --save vue3-slide-verify登录页面引入 template 下 <template><div class"login"><el-card class"cover" v-if"loginUser.data.user"><slide-verifyref"block"slider-text"向右滑动-&…

实验室预约系统设计与实现

实验室预约系统的设计 摘 要 目前各大学的实验项目日益繁多&#xff0c;如何合理预约实验室&#xff0c;已经成为当今各个大学实验室课程预约的难题。因此&#xff0c;这个实验室预约系统就是研究实验室预约的相关问题。实验室预约系统的设计主要是基于B/S模型&#xff0c;在W…

MySQL--MySQL索引事务

事务的概念 事务指逻辑上的一组操作&#xff0c;组成这组操作的各个单元&#xff0c;要么全部成功&#xff0c;要么全部失败。 在不同的环境中&#xff0c;都可以有事务。对应在数据库中&#xff0c;就是数据库事务。 使用 &#xff08;1&#xff09;开启事务&#xff1a;start…

VHOST-SCSI代码分析(2)VHOST SCSI驱动分析

在HOST内核中创建/dev/vhost-scsi&#xff0c;并提供用户态相关接口&#xff0c;在文件driver/vhost/scsi.c中。 对于/dev/vhost-scsi的ioctl调用包含如下类型&#xff1a; &#xff08;1&#xff09;VRING相关的系统调用 &#xff08;2&#xff09;VHOST SCSI相关的系统调用 …

【重新定义matlab强大系列十三】直方图 bin 计数和分 bin 散点图

&#x1f517; 运行环境&#xff1a;Matlab &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f91…

Web前端大作业html+css静态页面--掌****有限公司

文章目录 前言 一、效果图 二、代码展示 1.html 2.css部分 总结 前言 对于大一新生来说&#xff0c;期末考试和专业结课作业可能会带来很大的压力。特别是涉及到网页设计和编写的作业&#xff0c;可能让人感到无从下手。例如&#xff0c;web实训大作业、网页期末作业、web课程与…

四、C#—变量,表达式,运算符(2)

&#x1f33b;&#x1f33b; 目录 一、表达式1.1 什么是表达式1.2 表达式的基本组成 二、运算符2.1 算术运算符2.1.1 使用 / 运算符时的注意事项2.1.2 使用%运算符时的注意事项 2.2 赋值运算符2.2.1 简单赋值运算符2.2.2 复合赋值运算符 2.3 关系运算符2.4 逻辑运算符2.4.1 逻辑…

nexus 5x 刷机记录

1. 参考链接 https://d1ag0n.asia/archives/nexus5x%E5%88%B7android81root https://github.com/r0ysue/AndroidSecurityStudy/blob/master/FRIDA/A01/README.md 2. 下载工具 adb ,fastboot 官网的下载地址 &#xff1a; https://developer.android.com/studio/releases/pla…

高级视频和直播应用程序:Challenge 1.1.8 源码

您是否正在寻找高级视频和直播应用程序&#xff1f; 那么挑战就是您的完美选择。终极视频和直播挑战平台。凭借其尖端功能&#xff0c;Challenge 为用户和所有者提供了独特且引人入胜的体验。 通过购买挑战代码&#xff0c;您将可以使用以下令人兴奋的功能&#xff1a; 故事&…

学术团体的机器人相关分会和机器人相关大赛的说明

1. 中国机械工程学会 &#xff08;机器人分会&#xff09; 2017年成立&#xff0c;地点 华中科技大学 &#xff1a;中国机械工程学会机器人分会在汉成立 (huanqiu.com) 链接&#xff1a;中国机械工程学会 (cmes.org) 侧重点&#xff1a;工业机械臂、工厂和物流相关的移动机…

第 363 场 LeetCode 周赛题解

A 计算 K 置位下标对应元素的和 模拟 class Solution { public:int pop_cnt(int x) {//求x的二进制表示中的1的位数int res 0;for (; x; x >> 1)if (x & 1)res;return res;}int sumIndicesWithKSetBits(vector<int> &nums, int k) {int res 0;for (int i…

做一个有灵魂的软件测试员

有没有觉得自己每天的工作千篇一律&#xff0c;每天一上班就盼着下班&#xff1f; 一个月似乎能令自己开心的时间也就是发工资的那一天&#xff1f; 自己的工作生活总感觉被人牵着走&#xff0c;兜兜转转过了一年又一年&#xff1f; 测试员的工作性质决定了与重复、枯燥和乏…

自定义实现简易版ArrayList

文章目录 1.了解什么是顺序表2.实现哪些功能3.初始化ArrayList4.实现功能接口遍历顺序表判断顺序表是否已满添加元素指定下标添加元素自定义下标不合法异常判断顺序表是否为空查找指定元素是否存在查找指定元素返回下标获取指定下标的元素顺序表为空异常修改指定下标元素的值删…

【深度学习实验】线性模型(三):使用Pytorch实现简单线性模型:搭建、构造损失函数、计算损失值

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入库 1. 定义线性模型linear_model 2. 定义损失函数loss_function 3. 定义数据 4. 调用模型 5. 完整代码 一、实验介绍 使用Pytorch实现 线性模型搭建构造损失函数计算损失值 二、…

5-1 Dataset和DataLoader

Pytorch通常使用Dataset和DataLoader这两个工具类来构建数据管道。 Dataset定义了数据集的内容&#xff0c;它相当于一个类似列表的数据结构&#xff0c;具有确定的长度&#xff0c;能够用索引获取数据集中的元素。 而DataLoader定义了按batch加载数据集的方法&#xff0c;它是…

无涯教程-JavaScript - EVEN函数

描述 EVEN函数返回四舍五入到最接近的偶数整数的数字。您可以使用此功能来处理两个项目。 语法 EVEN (number)争论 Argument描述Required/OptionalNumberThe value to round.Required Notes 如果数字为非数字,则EVEN返回#VALUE!错误值。 不管数字的符号如何,当从零开始调…

VisualStudio配置驱动远程部署

目标机器开启ping命令 默认情况下&#xff0c;Windows出于安全考虑不允许外部主机对其进行Ping测试。 允许ICMP回显 设置如下&#xff1a; 打开win7防火墙设置界面 左边的菜单中选择 【高级设置】 在弹出的 【高级安全 Windows 防火墙】 界面&#xff0c;选择 【入站规则】 …

Java常见面试题(含答案,持续更新中~~)

目录 1、JVM、JRE和JDK的关系 2、什么是字节码&#xff1f;采用字节码的最大好处是什么 3、Java和C的区别与联系 4、Java和GO的区别与联系 5、 和 equals 的区别是什么&#xff1f; 6、Oracle JDK 和 OpenJDK 的对比 7、String 属于基础的数据类型吗&#xff1f; 8、fi…

VHOST-SCSI代码分析(3)数据流处理

VHOST SCSI数据流如下所示&#xff1a; IO下发过程 虚拟机中应用态程序下发IO&#xff0c;依次经过VFS/文件系统层&#xff0c;BLOCK层&#xff0c;SCSI层&#xff0c;经VIRTIO SCSI驱动virtscsi_commit_rqs访问寄存器通知HOST内核中VHOST设备&#xff08;VHOST KICK过程&#…