Spring通过工厂创建对象的三种方法详解(工厂设计模式)
1.场景描述
在创建对象的过程中,常常创建出的对象并不能直接使用,它可能需要若干步复杂的步骤,处理完成后才能正常使用。比如有一个网络连接的类NetConn,类中有加载配置文件的方法load(),测试网络连通性的方法ping(),连接网络的方法conn(),登陆方法login(),登陆成功发送数据的方法sendData()。当我们创建了NetConn类的对象时,并不能直接使用该对象去发送数据。因为前面还有一系列的步骤需要执行,只有执行完毕,登陆成功后才能发送数据。
如下图,创建对象后只有执行完成图中红框处的步骤后,才能正常调用sendData()方法发送数据。
2.传统的spring创建对象处理
如下图,通过传统的方法配置,让spring创建对象。但是在spring只是创建了NetConn 对象,并没有执行里面的方法,所以此时得到的对象conn并不能直接使用。还需要依次调用load()加载配置文件,ping()测试连通性等方法,十分繁琐。
测试验证,普通方法创建的对象不能直接使用 ,需要依次调用NetConn 方法
3.工厂设计模式
通过2中普通的spring创建对象方法,思考能不能让spring在创建好对象后先调用好里面的前置方法,,然后返回给我们可以直接使用的对象呢,这就引申出了工厂设计模式。
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。简单理解为写代码的套路,遇到什么样的问题就用什么样的套路。
解决上述问题,可以采用静态工厂,实例工厂,spring工厂实现,三种方法根据个人喜好任选一种即可。
3.1通过静态工厂创建对象
很多的时候,我们面对的类是无法通过无参构造去创建的,例如该类没有无参构造、是一抽象类 等等情况 ,此时无法要求spring通过无参构造创建对象,此时可以使用静态工厂 方式创建对象。
实现过程:创建NetConnStaticFactory类,在该类中创建静态方法getInstance()用来返回可以使用的NetConn对象。
当spring 扫描applicationContext.xml 中的bean 时,读取到配置的factory-method,spring就知道这是一个静态工厂,它就不会在去通过反射创建对象,它就会根据配置找打对应的工厂类并调用factory-method配置的方法。方法调用后返回了NetConn对象,spring将这个对象存在spring内部的Map中,key就是bean中配置的id,所以在通过spring获取到的NetConn对象,就能直接使用,调用sendData()方法发送数据。
applicationContext.xml 中的代码
<?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="netConn" class="cn.ww.beans.NetConnStaticFactory" factory-method="getInstance"/></beans>
静态工厂类NetConnStaticFactory
package cn.ww.beans;/*** 静态工厂*/
public class NetConnStaticFactory {/*** 对于静态工厂,一般不会让对象被外界new出来,所以将* 构造器设置为private*/private NetConnStaticFactory(){}/*** 设置静态方法getInstance(),返回可以使用的返回NetConn对象* @return 返回NetConn对象*/public static NetConn getInstance(){NetConn conn = new NetConn();conn.load();conn.ping();conn.conn();conn.login();return conn;}}
网络连接类NetConn
package cn.ww.beans;/*** 网络连接的类*/
public class NetConn {/*** 加载配置文件*/public void load(){System.out.println("网络配置文件加载中");}/*** 测试网络连通性*/public void ping(){System.out.println("测试网络连通性");}/*** 连接网络*/public void conn(){System.out.println("连接网络");}/*** 登录*/public void login(){System.out.println("登陆");}/*** 登录成功发送数据*/public void sendData(){System.out.println("登陆成功,发送数据");}
}
测试代码
/*** 测试类*/
public class DemoTest {/*** 通过spring获取对象并调用方法*/@Testpublic void test02(){//1.初始化spring容器ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//2.通过spring容器获取bean,getBean中的person 为applicationContext 配置文件中的 bean的idNetConn netConn = (NetConn) context.getBean("netConn");//3.调用方法sendData()发送数据netConn.sendData();//4.关闭spring容器//ApplicationContext 是接口,没有close方法,需要强转关闭((ClassPathXmlApplicationContext)context).close();}
测试结果,返回的对象能够直接使用
静态工厂创建对象过程总结如下:
3.2实例工厂创建对象
实例工厂也可以解决类是无法通过无参构造创建的问题,解决的思路和静态工厂类似,只不过实例工厂提供的方法不是静态的。spring需要先创建出实例工厂的对象,在调用实例工厂对象上指定的普通方法来创建对象。所以实例工厂也需要配置到Spring中管理。
aplicationContext.xml的配置如下:
<?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="netConnInstanceFactory" class="cn.ww.beans.NetConnInstanceFactory" /><bean id="netConn" factory-bean="netConnInstanceFactory" factory-method="getInstance"/>
</beans>
NetConnInstanceFactory类:
package cn.ww.beans;/*** 实例工厂创建对象*/
public class NetConnInstanceFactory {/*** 设置方法getInstance(),返回可以使用的返回NetConn对象* @return 返回NetConn对象*/public NetConn getInstance(){NetConn conn = new NetConn();conn.load();conn.ping();conn.conn();conn.login();return conn;}
}
其他类保持不变,测试结果如下:
实例工厂创建对象总结如下:
3.3 Spring工厂创建对象
Spring内置了工厂接口,也可以通过实现这个接口来开发Spring工厂,通过这个工厂创建对象。
aplicationContext.xml的配置如下:
<?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"><!--spring工厂--><bean id="netConn" class="cn.ww.beans.NetConnSpringFactory"/>
</beans>
NetConnSpringFactory类
package cn.ww.beans;import org.springframework.beans.factory.FactoryBean;/*** Spring工厂方法*/
public class NetConnSpringFactory implements FactoryBean<NetConn> {/***生产对象的方法*/@Overridepublic NetConn getObject() throws Exception {NetConn conn = new NetConn();conn.load();conn.ping();conn.conn();conn.login();return conn;}/*** 获取目标对象类型的方法*/@Overridepublic Class<?> getObjectType() {return NetConn.class;}/*** 用来控制目标对象是否是单例的方法* false:多例--例如用户的购物车对象* true:单例*/@Overridepublic boolean isSingleton() {return true;}
}
其他类保持不变,测试结果如下:
Spring工厂创建对象过程总结如下:
Spring通过工厂创建对象的三种方法详解(工厂设计模式)相关推荐
- python 命令-python解析命令行参数的三种方法详解
这篇文章主要介绍了python解析命令行参数的三种方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 python解析命令行参数主要有三种方法: ...
- 查看登陆系统用户的信息的三种方法详解
查看登陆系统用户的信息的三种方法详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.who这个命令显示可以谁在登陆,但是这个有很多的花式玩法,这个命令超简单 语法:who [O ...
- C语言求最大公约数三种方法详解
C语言求最大公约数三种方法详解 题目要求 常用写法(穷举法) 辗转相减法 辗转相除法 main函数 整体代码 题目要求 运行最大公约数的常用算法,并进行程序的调式与测试. 常用写法(穷举法) 从两个数 ...
- 新浪微博怎么推广引流,微博推广引流的三种方法详解
新浪微博怎么推广引流,微博推广引流的三种方法详解,#推广#营销 微博营销有哪些特点?#百收网SEO@千行助推 大家好,上一次内容讲了生意人如何将客户引流到自己的微信上去,受到很多朋友的喜爱,那么这一期 ...
- eclipse java 逆向工程_Mybatis 逆向工程的三种方法详解
Mybatis 逆向工程 逆向工程通常包括由数据库的表生成 Java 代码 和 通过 Java 代码生成数据库表.而Mybatis 逆向工程是指由数据库表生成 Java 代码. Mybaits 需要程 ...
- Php 链式执行,PHP实现链式操作的三种方法详解
本文实例讲述了PHP实现链式操作的三种方法.分享给大家供大家参考,具体如下: 在php中有很多字符串函数,例如要先过滤字符串收尾的空格,再求出其长度,一般的写法是: strlen(trim($str) ...
- 链表逆置(三种方法详解)
@Achievek 6-1 单链表逆转 (20 point(s)) 本题要求实现一个函数,将给定的单链表逆转. ##函数接口定义: List Reverse( List L ); 其中List结构定义 ...
- 记录Nginx的升级实践以及实现的三种方法详解
方法一: 对于现在有的环境是通过源码包安装nginx的,由于库文件都存在,要升级nginx直接在虚拟机上编译安装好包 然后打包 ,更新到线上机器的/opt/nginx1.x上. 测试如下: scp n ...
- JS截取字符串的三种方法详解
本文详细讲解了JS截取字符串的三种方法,文中通过示例代码介绍的非常详细.对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 JS提供三个截取字符串的方法,分别是:slice(),subst ...
最新文章
- 软件工程第二次课后作业——Gaoooo
- xp用光盘安装linux系统安装教程视频,光盘重装xp系统图文教程
- 初探Firewalld
- 方舟原始恐惧mod生物代码_重磅!命令与征服和红色警戒源代码在GitHub公布了
- mysql 查询字段中是否存在空格的_mysql查询字段中带空格的值的sql语句
- Core IO学习心得
- stylus之条件(Conditionals)
- 安装.Net Standard 2.0, Impressive
- 添加form表单_Django实战:如何使用djangocrispyforms美化Bootstrap 4表单
- 电脑机房用成品——名词解释
- php判断手机 跳转代码,php判断客户端是手机设备然后跳转到手机站
- 选择爱人的数学方法(经典秘书问题)
- python lnum_python 基础笔记 — 数据类型之数字
- HowNet文件介绍
- FPGA学习笔记06——数电基础知识
- 山西省太原市、运城市、大同等市全面推行建筑工地劳务实名制
- 计算机网络应用答题卡,计算机软考中高级答题卡填涂注意事项
- SQL应用·:用SQL分析供应商营业额
- 怎么给自己的电脑连接打印机
- 达芬奇密码 第七十一章
热门文章
- Flink Redis Sink
- 户外最好的装备是高清卫星地图通过gmap gee地图寻找露营点,野钓
- MSSQLSERVER订阅发布闭坑指南
- 2021春节期间各区县单位新冠疫情防控钉钉解决方案
- 【BZOJ2217】[Poi2011]Lollipop 乱搞
- mongodb高可用集群01---单实例、主从模式、一主多从模式
- [附源码]Nodejs计算机毕业设计怦然心动网上服装商城Express(程序+LW)
- siege 用户登录_siege--Web性能压测工具
- java new Filereader_Java FileReader类
- Vscode 快捷键生成代码片段