Spring通过工厂创建对象的三种方法详解(工厂设计模式) | 您所在的位置:网站首页 › 静态工厂方法和实例工厂方法 › 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 中的代码 静态工厂类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获取对象并调用方法 */ @Test public void test02(){ //1.初始化spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.通过spring容器获取bean,getBean中的person 为applicationContext 配置文件中的 bean的id NetConn netConn = (NetConn) context.getBean("netConn"); //3.调用方法sendData()发送数据 netConn.sendData(); //4.关闭spring容器 //ApplicationContext 是接口,没有close方法,需要强转关闭 ((ClassPathXmlApplicationContext)context).close(); }测试结果,返回的对象能够直接使用 静态工厂创建对象过程总结如下: 3.2实例工厂创建对象实例工厂也可以解决类是无法通过无参构造创建的问题,解决的思路和静态工厂类似,只不过实例工厂提供的方法不是静态的。spring需要先创建出实例工厂的对象,在调用实例工厂对象上指定的普通方法来创建对象。所以实例工厂也需要配置到Spring中管理。 aplicationContext.xml的配置如下: 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的配置如下: NetConnSpringFactory类 package cn.ww.beans; import org.springframework.beans.factory.FactoryBean; /** * Spring工厂方法 */ public class NetConnSpringFactory implements FactoryBean { /** *生产对象的方法 */ @Override public NetConn getObject() throws Exception { NetConn conn = new NetConn(); conn.load(); conn.ping(); conn.conn(); conn.login(); return conn; } /** * 获取目标对象类型的方法 */ @Override public Class getObjectType() { return NetConn.class; } /** * 用来控制目标对象是否是单例的方法 * false:多例--例如用户的购物车对象 * true:单例 */ @Override public boolean isSingleton() { return true; } }其他类保持不变,测试结果如下: Spring工厂创建对象过程总结如下:
|
CopyRight 2018-2019 实验室设备网 版权所有 |