Spring 工厂方法与FactoryBean(实例化Bean) 您所在的位置:网站首页 静态工厂方式实例化管理方案设计 Spring 工厂方法与FactoryBean(实例化Bean)

Spring 工厂方法与FactoryBean(实例化Bean)

2024-07-11 09:45| 来源: 网络整理| 查看: 265

该篇博客关于工厂方法与FactoryBean,其实就是在Spring中不再使用Spring创建Bean实例,而是利用工厂方法与FactoryBean把Bean创建过程转移到开发者手中

该篇博客目录 1、理解工厂方法和FactoryBean是干什么的 2、静态工厂方法实例化Bean 3、工厂方法实例化Bean 4、FactoryBean实例化Bean(工厂Bean) 一、理解工厂方法和FactoryBean是干什么的

笔者认为这一块在本篇博客是最重要的,你得理解工厂方法和FactoryBean是干什么的,以及它和哪些是同类

首先通常在Spring中,我们会利用XML或者注解的方式类配置bean。而在XML方式中有三种方式来实例化bean 反射模式工厂方法模式FactoryBean模式

其中经常会用到反射模式,即在bean的配置中,声明bean的全类名,而本博客笔者将会介绍工厂模式和FactoryBean模式下实例化bean,对两种模式深入理解其思想

二、静态工厂方法实例化Bean(Static Factory Method)

考虑一个场景,在Spring中将一个单例类配置Bean。一般来说,单例类的实例只能通过静态工厂方法创建(笔者这里在《Spring IN ACTION》的例子上进行扩展):以下例子一个舞台类,舞台只有一个,即采用静态工厂方法

Stage.java

package com.linjie.staticfactory; /** * @author LinJie * @Description:这是一个舞台单例类(所以需要静态工厂方法) * 每个参赛者用同一个舞台 */ public class Stage { private static Stage instance; public static Stage getInstance() { if(instance == null){ instance = new Stage(); } return instance; } //搭建舞台完成 public void CreateStageSuccess() { System.out.println("舞台搭建完成,舞者可以上台了"); } }

Dancer.java(舞者类)

package com.linjie.staticfactory; /** * @author LinJie * @Description:这是每个舞者的类,但他们使用同一个舞台 */ public class Dancer { private Stage stage; /** * @param stage the stage to set */ public void setStage(Stage stage) { this.stage = stage; } //LinJie dancer上台 public void Show() { stage.CreateStageSuccess(); System.out.println("LinJie dancer上台"); } }

测试类

package com.linjie.staticfactory; /** * @author LinJie * @Description:这是每个舞者的类,但他们使用同一个舞台 */ public class Dancer { private Stage stage; /** * @param stage the stage to set */ public void setStage(Stage stage) { this.stage = stage; } //LinJie dancer上台 public void Show() { stage.CreateStageSuccess(); System.out.println("LinJie dancer上台"); } }

applicationContext.xml

结果

舞台搭建完成,舞者可以上台了 LinJie dancer上台

注意:Stage没有公开的构造方法,取而代之的是,静态方法getInstance()每次调用都返回相同的实例(因为舞台只有一个),那么在Spring中如何把没有公开构造方法的Stage配置为一个Bean呢?

可以看到在applicationContext.xml中看到 factory-method:允许我们调用一个指定的静态工厂方法,从而代替构造方法来创建一个类的实例(即指定静态工厂方法名)class:不再是Bean实例的实现类,而是Bean实例的静态工厂类(上面的例子没有体现这一点,下面的例子根据这一点来实现)如果静态工厂方法需要参数,使用为其配置

Stage.java(一个舞台类,可传名字)

package com.linjie.staticfactory; /** * @author LinJie * @Description:一个舞台类,可以给舞台赋值(其实这里我只想演示传参) */ public class Stage { private String name; /** * @param name the name to set */ public void setName(String name) { this.name = name; } //搭建舞台 public void Show() { System.out.println(name+"舞台搭建完成"); } }

staticfactory.java(静态工厂方法实现类)

package com.linjie.staticfactory; /** * @author LinJie * @Description:这是一个静态工厂方法的类,用于创建单例舞台 */ public class staticfactory { private static Stage instance; public static Stage getInstance() { if(instance == null){ instance = new Stage(); } return instance; } }

测试类

package com.linjie.staticfactory; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class staticFactoryBean { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Stage stage = (Stage) context.getBean("stage"); stage.Show(); } }

applicationContext.xml

结果

这里写图片描述

注意:这里的class属性的值不是Bean实例的实现类,而是生成Bean实例的静态工厂类

三、工厂方法实例化Bean(Instance Factory Method)

ABean.java(一个Bean实例的实现类)

package com.linjie.factory; /** * @author LinJie * @Description */ public class ABean { //利用工厂方法实例化Bean成功显示 public void show() { System.out.println("工厂方法实例化Bean成功"); } }

FactoryBean.java(工厂方法)

package com.linjie.factory; /** * @author LinJie * @Description:工厂方法实例化Bean */ public class FactoryBean { public ABean getABean() { return new ABean(); } }

测试类

package com.linjie.factory; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class FactoryTest { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ABean abean = (ABean) context.getBean("abean"); abean.show(); } }

applicationContext.xml

结果

这里写图片描述

在applicationContext的属性中 factory-bean:指定工厂方法所在的工厂类实例(即工厂方法bean的id,用法与ref类似)factory-method:还是指定工厂方法名也可以通过来指定方法调用参数 四、FactoryBean实例化Bean

FactoryBean是Spring容器提供的一种可以扩展容器对象实例化逻辑的接口,请不要将其与容器名称BeanFactory相混淆。FactoryBean,其主语是Bean,定语是Factory,也就是说,它本身与其他注册到容器的对象一样,只是一个Bean而已,只不过这里类型的Bean本身就是生产对象的工厂

应用场景

当某些对象的实例话过程过于烦琐,通过XML配置过于复杂,使我们宁愿使用Java代码来完成这个实例化过程的时候,或者,某些第三方库不能直接注册到Spring容器中的时候,就可以实现org.spring-framework.beans.factory.FactoryBean接口,给出自己的对象实例化代码。当然实现自定义工厂也是可以的。但是FactoryBean是Spring的标准

使用方法

1、创建FactoryBean的实现类

2、实现以下三个方法

- public String getObject() throws Exception:该方法返回该FactoryBean“生产”的对象。我们需要实现该方法以给出自己对象实例化逻辑 - public Class getObjectType():该方法仅返回getObject()方法所返回的对象的类型。如果预先无法确定,则返回null - public boolean isSingleton() :该方法返回结果用于表明,getObject()“生产”的对象是否要以singleton(单例)形式存于容器中。如果以singleton形式存在,则返回true,否则返回false

nameFactoryBean实现类

package com.linjie.factorybean; import org.springframework.beans.factory.FactoryBean; public class nameFactoryBean implements FactoryBean { //该方法返回该FactoryBean“生产”的对象 //我们需要实现该方法以给出自己对象实例化逻辑 @Override public String getObject() throws Exception { return new String("linjie"); } //该方法仅返回getObject()方法所返回的对象的类型 //如果预先无法确定,则返回null @Override public Class getObjectType() { return null; } //该方法返回结果用于表明,getObject()“生产”的对象是否要以singleton(单例)形式存于容器中 //如果以singleton形式存在,则返回true,否则返回false @Override public boolean isSingleton() { return false; } }

测试类

package com.linjie.factorybean; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class factorybeanTest { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); String bean = (String) context.getBean("bean"); System.out.println(bean); } }

applicationContext.xml

结果

这里写图片描述

FactoryBean和BeanFactory区别 FactoryBean:就是笔者上文阐述的,以Bean结尾,表示它是个Bean,它并不是简单的Bean,而是一个能生产对象或者修饰对象的工厂BeanBeanFactory:它是Spring IoC容器的一种形式,提供完整的IoC服务支持,也可以看出主语是Factory,即是一个管理Bean的工厂,关于BeanFactory可以转战笔者另一篇博客https://blog.csdn.net/w_linux/article/details/80025048 参考

《Spring揭秘》

《Spring IN ACTION》



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有