前言
Spring是目前Java企业级开发应用广泛的框架之一,其具有强大的生态,且得益于其提供的高扩展能力,能够减少开发成本,提高开发效率。如此优秀的框架,当然离不开各种设计模式,本文主要介绍设计模式中的工厂模式在spring框架中的应用。
一、工厂模式介绍
工厂模式属于三种设计模式分类中的创建型模式。工厂模式主要是将创建对象的过程交给工厂进行处理,通过工厂提供给我们需要创建的对象,而不用自己直接去进行对象的创建。工厂模式包含三种:简单工厂模式(其不符合设计模式的开闭原则,不属于23中设计模式之一)、工厂方法模式以及抽象工厂模式,下面对每个模式进行逐一介绍。
1、简单工厂模式
(1)静态工厂模式
在创建方法中根据需要返回相对应的对象,当然,有新增对象的时候,需要修改方法,这样便会破坏开闭原则。下面用代码举个例子。
简单工厂模式中的三种角色:
抽象产品
具体产品
具体工厂
//电脑产品
public class Computer{
}
//Asus电脑
public class AsusComputer extends Computer{
}
//Dell电脑
public class DellComputer extends Computer{
}
//电脑创建工厂
public class ComputerFactory{
public enum ComputerType{
ASUS,DELL;
}
//创建方法:当有新的电脑产品的增加时,需要在create方法中进行添加
static Computer create(ComputerType computerType){
if(computerType.equals(ComputerType.ASUS)){
return new AsusComputer();
}
if(computerType.equals(ComputerType.DELL)){
return new DellComputer();
}else{
return null;
}
}
}
(2)利用反射机制实现的简单工厂
由于静态工厂模式会破坏开闭原则,因此,从静态工厂模式扩展出一种利用反射可以动态添加创建对象的简单工厂模式。通过新对象注册到容器中,并利用反射机制来实现对象的创建,从而不用修改代码,不会违背开闭原则。还是以电脑产品为例
//电脑产品
public class Computer{
}
//Asus电脑
public class AsusComputer extends Computer{
}
//Dell电脑
public class DellComputer extends Computer{
}
//电脑创建工厂
public class ComputerFactory{
//注册容器
private static Map<String,Class<? extends Computer>> computerContext = new ConcurrentHashMap<>();
//注册电脑类型
static void registerComputer(String computerType,Class<? extends Computer> cls){
computerContext.put(computerType,cls);
}
//创建方法:当有新的电脑产品的增加时,可以通过registerComputer方法将产品注册进来,不用改变代码
static Computer create(String computerType){
Computer needComputer = computerContext.get(computerType).newInstance();
if(needComputer != null){
return needComputer;
}else{
return null;
}
}
}
简单工厂模式,不够抽象,耦合度高,虽然可以利用反射机制来解决静态工厂模式的弊端,但是需要使用注册空间以及反射,在创建对象量大的场景下回降低效率,因此,变回有工厂方法模式来解决这些弊端。
2、工厂方法模式
工厂方法模式是简单工厂模式基础上的变形,当需要新增新对象时,只需要实现相对应的工厂接口方法来创建对象,无需修改工厂代码,从而符合开闭原则。
抽象工厂模式的主要角色:
抽象产品
具体产品
抽象工厂
具体工厂
//电脑产品
public class Computer{
}
//Asus电脑
public class AsusComputer extends Computer{
}
//Dell电脑
public class DellComputer extends Computer{
}
//电脑创建工厂接口
public interface ComputerFactory{
public Computer createComputer();
}
//AsusComputer创建工厂
public class AsusComputerFactory implements ComputerFactory {
public Computer createComputer(){
return new AsusComputer();
}
}
//DellComputer创建工厂
public class DellComputerFactory implements ComputerFactory {
public Computer createComputer(){
return new DellComputer();
}
}
//...需要创建更多对象时,去实现ComputerFactory接口即可,这样即降低了耦合度,又不违背开闭原则
工厂方法模式,降低了耦合度,提高扩展性,符合开闭原则,但是其存在一个问题,即仅仅只能在同一个维度上进行对象的创建,这样就引出了抽象工厂模式。
3、抽象工厂模式
抽象工厂模式,可以认为是工厂方法模式的增强版,其提供了多种对象的创建方法,使得工厂方法模式可以在不同维度上进行不同对象的创建。
//电脑产品
public class Computer{
}
//Asus电脑
public class AsusComputer extends Computer{
}
//Dell电脑
public class DellComputer extends Computer{
}
//服务器产品
public class Server{
}
//Asus服务器
public class AsusServer extends Server{
}
//Dell服务器
public class DellServer extends Server{
}
//创建工厂接口
public interface Factory{
public Computer createComputer();
public Server createServer();
}
//Asus创建工厂
public class AsusFactory implements Factory{
public Computer createComputer(){
return new AsusComputer();
}
public Server createServer(){
return new AsusServer();
}
}
//Dell创建工厂
public class DellFactory implements Factory {
public Computer createComputer(){
return new DellComputer();
}
public Server createServer(){
return new DellServer();
}
}
有了抽象工厂模式,便可以在多个维度进行对象的创建,减少了工厂方法对象创建的单一性。
二、spring框架中工厂模式的重要应用
上面简单介绍了工厂模式的三种类型,接下来我们就来看看Spring框架中有哪些地方运用到了工厂模式吧。
1、BeanFactory
相信大家都对BeanFactory不陌生,直接翻译就是Bean工厂。Spring框架的两个关键就是IOC和AOP,其中IOC的设计当然就涉及到BeanFactory;有了Spring框架,我们就很少自己进行对象的创建了,而我们使用到的对象当然就是交给Spring的工厂模式来创建的了。其中BeanFactory是Spring容器的顶层接口,也是Bean工厂最上层的接口,其会有很多工厂实现例如,我们可以把BeanFactory看成是一种工厂方法模式。
从BeanFactory接口的结构我们可以看出,通过getBean重载方法,为我们创建不同的Bean对象,当然其也有很多工厂实现,例如我们用的最多的DefaultListableBeanFactory,还有SimpleJndiBeanFactory、StaticListableBeanFactory等等。
Spring工厂模式的应用还加入了反射及配置。通过对各种配置,例如xml,注解等等解析成BeanDefinition,然后根据不同工厂要求通过反射创建不同的Bean对象,这样开发过程中,我们可以将需要创建的对象通过配置等方式交给Bean工厂去完成,使用时直接获取便可。Bean工厂的设计,大大降低耦合度,并增强可扩展性,提高了代码的可维护性,符合设计模式的原则。
2、FactoryBean
讲完BeanFactory,再介绍另外一个工厂模式的应用FactoryBean,实际上,这两个接口都是用于创建对象,都可以看做是工厂方法模式的实现。BeanFactory是Spring的一个大工厂,创建着Spring框架运行过程中所需要的Bean;而FactoryBean是一个定制化工厂,其会存在于BeanFactory创建对象的过程中,当有需要时,会通过FactoryBean去自定制个性化的Bean,从而Spring框架提高扩展能力。
FactoryBean工厂通过getObject()方法来创建并返回对象,我们可以通过实现FactoryBean来定制化自己需要的Bean对象,因此,FactoryBean是一种典型的工厂方法模式的实现。
我们在引入其他框架整合Spring时,便会有很多桥接整合包,例如mybatis-spring等,其中就会有FactoryBean的实现,例如SqlSessionFactoryBean、MapperFactoryBean等,将需要整合的定制化Bean通过工厂方法的模式,加入进Spring容器中,从而大大降低了耦合程度,也为开发提供了扩展能力。
//FactoryBean接口
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
//对象创建方法,不同的对象去实现不同的FactoryBean工厂,通过工厂方法模式来实现Bean的定制化
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
总结
本文主要针对工厂模式的分类和实现进行了讲解,并对Spring框架中两个重要工厂模式的实现BeanFactory和FactoryBean进行了介绍。工厂模式的实现是Spring管理Bean对象的基础,也是Spring框架解耦和重要的扩展点。BeanFactory以及FactoryBean可以看做是工厂方法模式的实现,BeanFactory融合了反射以及配置,提高了工厂创建对象的灵活程度,FactoryBean为BeanFactory创建的对象提供了定制化的对象工厂实现,也能够提高Spring创建和管理对象的能力。
参考地址:https://blog.csdn.net/weixin_44420511/article/details/125185404