这更像是一个设计问题,而不是代码实现,但我希望有人可以提供帮助。

我面临的问题是我需要根据两个输入注入一个modelSerivce。 我非常肯定基于一些文档和SO问题,我想为此使用一个factorybean。

我的问题更多地涉及将使用factorybean创建的这些类的构造。 如何在工厂中重复使用单件bean而不是每次调用工厂时创建一个新类?

这是代码的样子:

东西界面:

public interface Thing {
    void Run();
}

ThingA实施:

public class ThingA implements Thing{
    public void Run() {
        System.out.println("In ThingA");
    }
}

ThingB实施:

public class ThingB implements Thing{
    public void Run() {
        System.out.println("In ThingB");
    }
}

ThingFactory实施:

public class ThingFactory {
    public Thing GetThing(String stateCode, Date date){
        Thing result;
        if(stateCode == "MA") {
            result = new ThingA();
        }
        else {
            result = new ThingB();
        }
        return result;
    }
}

我真正希望工厂做的是拉出一个已知的实现,而不是每次调用工厂时创建一个实现。 我也想通过这样的方式将我的工厂绑定到Spring框架:

ApplicationContext.getBean()

#1楼 票数:2

实际上我处理了同样的问题,这是我提出的解决方案。 我所依赖的主要技巧是,任何定义为单线程的bean都是在Spring初始化时由Spring实现的。 所以这就是我所做的:

  1. 在您的情况下,添加一个抽象类ThingImpl ,它实现您的Thing接口,并将成为您所有ThnigAThingB ...类的父级。 (或者只是将您的Thing界面更改为抽象类)
  2. 将您的ThingFactory更改为以下内容:

      public class ThingFactory { private static Map<String, Thing> instancesMap = new Hashmap<>() public static Thing getThing(String name) { return instancesMap.get(name); } public static addInstance(String name, Thing thing) { instancesMap.put(name, thing); } 

    }

  3. 在您的抽象父级中添加以下构造函数

public ThingImpl() { ThingFactory.addInstance(this.getClass().getSimpleName(), this); }

您的工厂根本不需要被定义为bean,但是所有Thing类都应该被定义为bean。 将要发生的事情是,当Spring初始化时,它会实现所有Thing类,并且作为自己初始化的一部分,每个Thing类都会将自己插入到工厂的地图中。 因此,您现在需要做的就是在代码中的任何地方都可以调用您的工厂:

ThingFactory.getThing("ThingA");
ThingFactory.getThing("ThingB");

#2楼 票数:1 已采纳

只需像往常一样将豆子作为单身人物保留在春季环境中。 将上下文注入工厂并根据业务规则从中提取bean。

public class ThingFactory {

    @Autowired 
    private ApplicationContext ctx;

    public Thing GetThing(String stateCode, Date date){
        Thing result;
        if(stateCode == "MA") {
            result = ctx.getBean("someBean")
        }
        else {
            result = ctx.getBean("someOtherBean")
        }
        return result;
    }
}

你可以更聪明,并使用一个方案来命名上下文中的bean:

@Service("Thing_MA")
public class ThingA implements Thing{
.
.
.
}

这为您的工厂购买了很好的声明式查找规则:

public class ThingFactory {
    public Thing GetThing(String stateCode, Date date){
        return (Thing) ctx.getBean("Thing_" + stateCode);

   }
}

#3楼 票数:0

如果您不想绑定代码弹簧框架,这意味着您不想使用BeanFactory并创建自己的工厂,那么您将不得不像自己一样创建对象

public class ThingFactory {

    private final static Thing thingA = new ThingA();
    private final static Thing thingB = new ThingB();

    public Thing GetThing(String stateCode, Date date){
        if(stateCode.equals("MA")) {
            return thingA;
        } else {
            return thingB;
        }
    }
}

如果你在这种情况下有更多的Thing实现,你只需创建一个地图并根据需要获取对象。

public class ThingFactory {

    private final static Map<String, Thing> beanMap = new Hashmap<>()

    public ThingFactory(){
        addThing("ThingA", new ThingA());
        addThing("ThingB", new ThingB());
    }

    public static Thing getThing(String name) {
      return beanMap.get(name);
    }      

    public static addThing(String name, Thing thing) {
       beanMap.put(name, thing);
    }

    public Thing GetThing(String stateCode, Date date){
        if(stateCode.equals("MA")) {
            return getThing("ThingA");
        } else {
            return getThing("ThingB");
        }
    }
}

但是,我建议你选择Spring的BeanFactory而不是创建自己的工厂,并与@Robert Moskal一起回答。

如果在应用程序启动时知道stateCode的值,您可以使用spring profiles来实现。

@Service
@Profile("ThingB")
public class ThingB implements Thing{
    public void Run() {
        System.out.println("In ThingB");
    }
}

  ask by Jamie Babineau translate from so

未解决问题?本站智能推荐:

3回复

从DI容器获取新实例的工厂方法

我正在尝试在Java Spring启动应用程序中创建工厂方法。 但是,我不想手动实例化一个对象,而是想从DI容器中获取它。 那可能吗? 调用getBean方法时出现错误“没有可用的'com.test.mp.service.PaymentServiceImplA'类型的合格Bean”。
2回复

工厂方法返回 Spring 服务

我想要一个返回服务的工厂类,我可以用它来做一些验证。 我实现了这个类 EventUpdateValidatorStrategy接口是这样的 EventSecondApprovalValidator是这个 其他EventApprovedValidator和EventAccounting
2回复

抽象工厂模式与2工厂方法

在一个带有(controller - services - dao - entity layers)的spring hibernate java项目中,我有抽象工厂模式(抽象类有2个抽象方法)。 在抽象工厂模式的实现类中,我有dao方法(运行命名查询)。 现在当请求来自另一个服务类的服务im
1回复

如何写子工厂链接到他们的总工厂(避免这些子工厂链接到另一个工厂)?

我使用 Spring 框架用 Java 编程。 但我有一个关于设计模式的问题。 我有一个 X 类,包含 3 个部分,3 个“大”部分:ABC 我为这个类创建了一个工厂,使用 3 个大的私有方法来构造 X 类型对象的 3 个部分。 问题如下:由于3个私有方法createA、createB和c
1回复

将物体传递到工厂

我有一个单例课程来管理我的所有服务。 我用工厂模式替换了这个单例。 所有服务都有一个initialize()和close() 。 我的大多数服务都接受构造函数参数,并且因服务而异-这是设计开始崩溃的地方。 我正在使用Spring Boot初始化我的singletonCache 。
2回复

这是工厂模式的完美问题吗?

我想以某种灵活性设计应用程序的文件存储部分,以便可以将文件存储在S3或Web服务器的硬盘驱动器上。 我还希望此功能在每个用户的基础上具有灵活性,因此,在他们的用户设置中,他们可以选择是否要将文件存储在S3或服务器文件系统中。 我在想这样的事情: 然后,我将有一个类似的方法:
1回复

春季:如何管理动态工厂?

我想创建一个工厂,但是使用Spring并不容易,而且我再次迷失在太空:p 这就是我想做的。 我有一个抽象类,它实现了多个接口(Runnable和一些个人接口) 我有一些从该抽象类扩展的类,我将它们称为:W,S和E:p和一些用于Abstract属性(docUnit)的类,它们称
1回复

基于Java的配置和工厂模式

假设我有一个类Fruit ,它是两个子类 - Apple和Grape : 在spring属性文件中,我有一个属性来决定在启动时注册哪个bean。 一次,我只会将Apple或Grape实例注册为bean。 该物业是: 在Java配置文件中,我使用@Value将String属性绑