Spring结合工厂模式

学习设计模式,不要进入一个误区生搬硬套,它是一种编程思想,结合实际使用,往往设计模式是混合使用的

工厂模式

核心本质: 使用工厂统一管理对象的创建,将调用者跟实现类解耦

我这里使用Spring容器的支持,实现起来将更加简单,只需要实现产品接口,就能产品就能自动注册到工厂,让工厂统一管理。以后有新的产品,不修改原来的代码,新产品实现产品接口,专注新产品的业务功能开发即可。

java 复制代码
package com.dj.factory;

/**
 * User: ldj
 * Date: 2024/1/28
 * Time: 13:38
 * Description: 产品类
 */
public interface Animal {

    void description();
}


@Component
public class Cat implements Animal {

    @Override
    public void description() {
        System.out.println("我是一只可爱的喵星人");
    }
}


@Component
public class Dog implements Animal {

    @Override
    public void description() {
        System.out.println("我是一只爱拆家的二哈");
    }
}
java 复制代码
package com.dj.factory;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * User: ldj
 * Date: 2024/1/28
 * Time: 13:11
 * Description: 工厂类
 */
@Component
public class AnimalFactory implements ApplicationContextAware {

    private static final Map<String, Animal> animalMap = new ConcurrentHashMap<>();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        register(applicationContext);
    }

    public static Animal getInstance(String beanName) {
        return animalMap.get(beanName);
    }

    public static void register(ApplicationContext applicationContext) {
        Map<String, Animal> beanMap = applicationContext.getBeansOfType(Animal.class);
        if (!CollectionUtils.isEmpty(beanMap)) {
            animalMap.putAll(beanMap);
        }
    }
}

其实注册这个动作还可以在产品类实现接口 InitializingBean 在重写方法进行注入类似这样:

还可以使用 @PostConstruct 自己写init方法,在init方法方法里调用工厂提供的注入方法

那么问题来了,有Spring容器管理的Animal的实现类我们还要必要自己写工厂类吗?于是继续优化代码:

java 复制代码
package com.dj.factory;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * User: ldj
 * Date: 2024/1/28
 * Time: 13:11
 * Description: 工厂类
 */
@Component
public class AnimalFactory implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        AnimalFactory.applicationContext = applicationContext;
    }

    public static Animal getInstance(String beanName) {
        return (Animal) applicationContext.getBean(beanName);
    }

}
相关推荐
saber_andlibert2 分钟前
TCMalloc底层实现
java·前端·网络
wangjialelele5 分钟前
平衡二叉搜索树:AVL树和红黑树
java·c语言·开发语言·数据结构·c++·算法·深度优先
m0_4811473311 分钟前
拦截器跟过滤器的区别?拦截器需要注册吗?过滤器需要注册吗?
java
Coder_Boy_14 分钟前
基于SpringAI的在线考试系统-相关技术栈(分布式场景下事件机制)
java·spring boot·分布式·ddd
独自破碎E15 分钟前
【BISHI15】小红的夹吃棋
android·java·开发语言
冻感糕人~17 分钟前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
啦啦啦_999922 分钟前
Redis实例-2
java
alice--小文子27 分钟前
cursor-mcp工具使用
java·服务器·前端
进阶小白猿28 分钟前
Java技术八股学习Day33
java·开发语言·学习
程序员敲代码吗34 分钟前
如何通过命令行启动COMSOL的参数化、批处理和集群扫描
java·c#·bash