本文完整代码地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/factorybean

FactoryBeanBeanFactory由于在命名上极其相似,一直以来困扰了不少的开发者。

BeanFactory,耳熟能详的Spring核心接口,提供IoC容器的最基本功能。但要解释FactoryBean一句话可能就说不清楚了。我们将从下面的例子逐步说明,FactoryBean是什么,它提供了什么样的能力。

/**  * 布料  * 包含颜色属性  * Created by OKevin On 2019/9/3  **/ public class Cloth {     private Red red;     //省略setter/getter方法 }

当初始化一个Cloth对象时,我希望Red对象也被赋值,此时我将在Cloth的构造方法中new一个Red对象。

public Cloth() {     red = new Red(); }

但是随着业务的发展,我希望Cloth的颜色属性将是Blue蓝色,这时我将修改代码将Red和Blue类抽象出一个Color接口,Cloth代码将重构:

/**  * 布料  * 包含颜色属性  * Created by OKevin On 2019/9/3  **/ public class Cloth {     private Color color;     public Cloth() {         color = new Blue();     }     //省略setter/getter方法 }

业务又进一步发展,Cloth类中的颜色属性将会根据一定的条件赋值为Red红色,此时我们将代码继续重构:

/**  * 布料  * 包含颜色属性  * Created by OKevin On 2019/9/3  **/ public class Cloth {     private Color color;     public Cloth() {         if (condition()) {             color = new Blue();             } else {             color = new Red();         }     }     //省略setter/getter方法 }

这样的代码的确能运行,但如果有新的条件继续加入到业务中,此时我们又将改动Cloth类的构造方法,而我们认为Cloth方法是一个比较核心的业务对象,不应该经常对它进行修改,并且在构造方法中对于Color对象创建过于冗余,不符合单一职责的原则,所以我们将Color对象的创建过程通过工厂方法模式来完成。

静态工厂方法

我们再次将Cloth类进行如下重构(为了使示例代码更加简洁,下面的示例将只创建Red对象):

/**  * 布料  * 包含颜色属性  * Created by OKevin On 2019/9/3  **/ public class Cloth {     private Color color;     public Cloth() {         color = StaticColorFactory.newInstance();     }     //省略setter/getter方法 }
/**  * 静态工厂方法  * Created by OKevin On 2019/9/3  **/ public class StaticColorFactory {     public static Color