博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
工厂方法与 FactoryBean(Spring对工厂模式的XML支持)
阅读量:7129 次
发布时间:2019-06-28

本文共 3865 字,大约阅读时间需要 12 分钟。

工厂方法与 FactoryBean

引子

直接依赖接口实现类的类Foo

public class Foo { private BarInterface barInstance;   public Foo()  {   // 我们应该避免这样做// instance = new BarInterfaceImpl();   }   // ... 复制代码

使用了工厂方法模式的Foo类可能定义:

public class Foo { private BarInterface barInterface;   public Foo()   {   // barInterface = BarInterfaceFactory.getInstance();   // 或者  // barInterface = new BarInterfaceFactory().getInstance();   } ... 复制代码

此时接口BarInterfaceBarInterfaceImpl解耦,BarInterfaceBarInterfaceFactory耦合,实现了替换BarInterface实现类只需要替换BarInterfaceFactory持有的实现类即可。

静态工厂方法(Static Factory Method)

不带参数的静态工厂方法:

静态工厂类:

public class StaticBarInterfaceFactory {   public static BarInterface getInstance()   {    return new BarInterfaceImpl();   } } 复制代码

Foo注入BarInterface的XML配置:

复制代码

其中,barInterface的注入方式为setter注入,为Foo类实例注入了BarInterfaceImpl的实例。且此处的id="bar"的bean指的是通过StaticBarInterfaceFactorygetInstance方法获得的BarInterfaceImpl实例。

注意id="bar"的bean属性factory-methodclass的作用

带参数的静态工厂方法:

静态方法带参数的静态工厂类:

public class StaticBarInterfaceFactory {   public static BarInterface getInstance(Foobar foobar)   {   return new BarInterfaceImpl(foobar);   } } 复制代码

为Foo注入 BarInterface 的XML配置:

复制代码

具体参数的使用在BarInterfaceImpl中实现,同上,此处的id="bar"的bean指的是通过 StaticBarInterfaceFactory 的 getInstance 方法获得的 BarInterfaceImpl 实例,构造参数foobar也是传递给BarInterfaceImp的。

注意<constructor-arg>节点的作用

非静态工厂方法(Instance Factory Method)

非静态方法工厂类:

public class NonStaticBarInterfaceFactory { public BarInterface getInstance()   {   return new BarInterfaceImpl(); }   ... 复制代码

为Foo注入 BarInterface 的XML配置:

复制代码

此处的工厂类作为普通bean注册到Spring容器中,而不是直接调用静态方法(需要实例化才能调用实例方法)。

如果非静态工厂方法调用时也需要提供参数的话,处理方式是与静态的工厂方法相似的,都可以通过<constructor-arg>来指定方法调用参数。

注意factory-bean属性的作用。

FactoryBean

FactoryBean是Spring容器提供的一种可以扩展容器对象实例化逻辑的接口,请不要将其与容器名称BeanFactory相混淆。它的实现类是专用于生产对象的bean。

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

FactoryBean定义:

public interface FactoryBean {     //返回产品类对象  Object getObject() throws Exception;   //返回产品类类型  Class getObjectType();  //返回产品类scope  boolean isSingleton(); } 复制代码

每次得到的日期都是第二天工厂实现类:

import org.joda.time.DateTime; import org.springframework.beans.factory.FactoryBean; public class NextDayDateFactoryBean implements FactoryBean {   public Object getObject() throws Exception {     return new DateTime().plusDays(1);   }   public Class getObjectType() {     return DateTime.class;   }   public boolean isSingleton() {     return false;   } } 复制代码

NextDayDateFactoryBean注册到Spring容器:

复制代码

注意id="nextDayDate"的bean没有使用factory-method属性就完成了依赖对象的生产,这里是FactoryBean接口的作用。

NextDayDateDisplayer类定义:

public class NextDayDateDisplayer {   private DateTime dateOfNextDay;   // 相应的setter方法  // ... } 复制代码

由此,我们实现了NextDayDateDisplayer不依赖NextDayDateFactoryBean即可得到依赖的DateTime实例,即Spring容器通过工厂模式实现了类依赖注入。

使用&获取FactoryBean的实例演示:

//以下所有assert均通过//获取工厂产品类DateTimeObject nextDayDate = container.getBean("nextDayDate"); assertTrue(nextDayDate instanceof DateTime);//获取FactoryBean类的对象本身Object factoryBean = container.getBean("&nextDayDate"); assertTrue(factoryBean instanceof FactoryBean); assertTrue(factoryBean instanceof NextDayDateFactoryBean); //通过上一步获得的FactoryBean获取工厂产品类DateTime的对象Object factoryValue = ((FactoryBean)factoryBean).getObject(); assertTrue(factoryValue instanceof DateTime); assertNotSame(nextDayDate, factoryValue); assertEquals(((DateTime)nextDayDate).getDayOfYear(),((DateTime)factoryValue).getDayOfYear()); 复制代码

Spring容器使用FactoryBean案例:

  • JndiObjectFactoryBean
  • LocalSessionFactoryBean
  • SqlMapClientFactoryBean
  • ProxyFactoryBean
  • TransactionProxyFactoryBean

转载于:https://juejin.im/post/5c1ca2f1f265da61736a432f

你可能感兴趣的文章
人机博弈-吃跳棋游戏(三)代移动
查看>>
spring bean范围
查看>>
【转】兼容性测试套件(CTS)框架用户手册
查看>>
express-session相关用法
查看>>
项目编号 总结
查看>>
OOAD之单例模式Singleton的6种写法
查看>>
Html与XSL字符转义
查看>>
java基金会成立Set
查看>>
PC-hosts 的使用 [可使电脑无法正常上网]
查看>>
PC-经典之“运行里面的密密”
查看>>
2015第30周二
查看>>
spring获取webapplicationcontext,applicationcontext几种方法详解
查看>>
利用 Html 元标记控制搜索引擎蜘蛛
查看>>
快速排名 让人疯狂的黑帽seo技术
查看>>
FF浏览器来帮助我们录制脚本
查看>>
UVa 10190 - Divide, But Not Quite Conquer!
查看>>
在VirtualBox安装OS X 10.10
查看>>
div 居中
查看>>
Scala 深入浅出实战经典 第65讲:Scala中隐式转换内幕揭秘、最佳实践及其在Spark中的应用源码解析...
查看>>
UIKit的手风琴菜单,单条展开和多条同时展开
查看>>