欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > spring 学习(工厂方式 实例化对象(静态工厂,实例化工厂,实现factorybean 规范))

spring 学习(工厂方式 实例化对象(静态工厂,实例化工厂,实现factorybean 规范))

2025/2/9 12:22:11 来源:https://blog.csdn.net/m0_74124657/article/details/145502790  浏览:    关键词:spring 学习(工厂方式 实例化对象(静态工厂,实例化工厂,实现factorybean 规范))

目录

前言

第一种:静态工厂方式实例化对象

静态工厂的特点

demo(案例)

第二种:实例工厂的方式

实例工厂和静态工厂的区别

demo(案例)

第三种:实现FactoryBean规范的方式

demo(案例)


前言

spring 实例化对象的几种方式

  • 使用 构造方法实例化对象  spring学习(spring-bean实例化(无参构造与有参构造方法实现)详解)-CSDN博客
  •  工厂方式创建对象。

工厂方式实例化对象又可以分为三种情况:

一种是静态工厂;另一种是实例工厂;还有一种实现FactoryBean方式;下面我们就这三种方式分别实现一下。

准备工作 :导入 spring-context 依赖

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.23</version></dependency>

第一种:静态工厂方式实例化对象

静态工厂的特点

通过属性factory-method来指定一个静态方法,在该静态方法中达到创建对象的目标并返回交给spring容器管理。

demo(案例)

在 IDEA 新建两个类 学生 类,老师类,当前使用 静态工厂方式 创建 学生类对象

根据是否提前在 目标类 写静态方法 有两者写法

  •  先在目标类中 写好 静态方法

spring 配置文件 中

Test 测试类

运行结果

 注意:factory -method 属性值 是 你添加的静态方法名。如果你事先没有确定好静态方法,可以根据提示自定义方法名,创建在目标类中


  • 先不在目标类中添加静态方法,而是在配置文件中 自定义 静态方法名,之后再目标类中完善方法

根据提示自定义方法名,自动创建在目标类中

重新运行结果是一样的

现在有一个问题 ,使用 学生类的静态方法,创建老师类对象 是否可行呢?

在 Test 测试类中

运行结果

发现,确实可以 创建 老师类对象。

在测试类,我想要获得是 学生类对象,但因为我在 学生类的添加的静态方法中,返回老师对象,最终结果打印的也是老师对象的地址。这个情况,我们常常戏称为 狸猫换太子

具体的底层代码细节如下

通过这个现象 思考几个问题

  • 1 学生类对象 创建了没有

观察

1 spring 配置文件是否有表示学生信息的bean 标签

2 静态方法中是否有通过new 关键字创建对象

  • 2 老师 类对象 有没有交给 spring 容器 管理

我认为 老师类 对象有spring 容器的参与,但实际上创建还是 new 出来的。

看下一个知识点: 实例化工厂 创建

总结 静态工厂 实例化对象

总结:采用静态工厂的方式去实例化对象,只需要在bean标签中指定一个静态方法即可,用factory-method属性来指定,方法名自已取,反正由idea自动帮我们创建好。然后我们只需要在创建好的静态方法中返回一个对象就搞定了。


第二种:实例工厂的方式

实例工厂和静态工厂的区别

  • 实例工厂的方式,是在静态工厂的基础上在sping 配置文件 中 添加一个 factory-bean 属性,并实现真正目标类的方法

  • 实例工厂创建对象 需要非静态方法,并且该方法是存在真正的创建对象的类中


demo(案例)

当前有 Ball ,Fruit 类 ,使用实例化工厂方式 创建 Ball 类对象

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 id="student" class="fs.exerise01.Student" factory-method="getObject"/>
<!--    实例工厂创建对象--><bean id="ball" class="fs.exerise02.Ball "></bean><bean id="fruit" class="fs.exerise02.Fruit" factory-method="getObject"  factory-bean="ball"></bean></beans>

发现 factory-bean 的属性值 和 把目标对象交给 容器生产的 唯一标识符 id 的值是息息相关

从上面的图片可以知道:

是spring 容器通过构造方法创建 Ball 类对象,后对象调用在Ball 类的getObject 方法来创建真正需要的目标对象


Ball 类代码

package fs.exerise02;public class Ball {public Ball getObject() {return new Ball();}
}

Test测试类代码

package fs.exerise02;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");Object bean = context.getBean("fruit");System.out.println(bean);}
}

运行结果

发现 表面上通过 getbean方法 获得 fruit 类对象方法,但实际是通过 实例化工厂方式创建ball类对象。真正做到了 移花接木的效果。

同样的道理,我们只需要修改Ball 类中的方法,可以任意创建目标对象?

如 之前在Ball 类中创建ball类对象。现在创建 fruit 类对象

其他的地方,一律不变!

运行结果

实例化工厂创建对象总结

1 使用实例化工厂创建对象,factory-bean 的属性值 表示真正调用本类的factory-method 属性值表示的方法

2 在本类方法中,我们可以修改方法,来实现任意对象的创建


第三种:实现FactoryBean规范的方式

demo(案例)

了解

Demo3 是 FactoryBean 接口的实现类,并重写  getObject 返回目标对象,getObjectType  返回 目标类的字节码文件,最终实现 Ball 类对象的创建

Demo3 类代码

package fs.exerise03;import fs.exerise02.Ball;
import org.springframework.beans.factory.FactoryBean;public class User implements FactoryBean<Ball> {// 返回一个Ball对象@Overridepublic Ball getObject() throws Exception {return new Ball();}
/// 返回Ball.class@Overridepublic Class<?> getObjectType() {return Ball.class;}
}

Test 测试类


package fs.exerise03;import fs.exerise02.Ball;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) throws Exception {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");Ball demo3 = (Ball)context.getBean("user");System.out.println(demo3.getObject());}}

运行结果

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com