当前位置: 首页 > 面试题库 >

使用Spring配置Abstract Factory的实现类

蒋烨然
2023-03-14
问题内容

对于我的应用程序,我有一个Scale接口和实现此接口的多个类,例如NormalizedScaleLogScale等。在我的一个服务中,我需要创建许多Scale,并且我想使用Spring定义应创建的Scale实现。
。我将如何实施这样的事情?

-

我当时正在考虑创建一个工厂ScaleFactory,就像在“抽象工厂模式”中那样,我可以调用它ScaleFactory.getScale()来获得我在Spring
XML中配置的任何实现的Scale:

class ScaleFactory {
    Class<? extends Scale> scaleImplClass;
    public static Scale getScale() {
        return scaleImplClass.newInstance();
    }
}


Scale myScale = ScaleFactory.getScale();

但是用这种方法,我如何配置ScaleFactory应该从Spring XML中使用哪种实现?

-

另一种选择是使ScaleFactorya @Service,然后将ScaleFactory自动连接到我的服务中:

@Autowired
ScaleFactory scaleFactory;

...

Scale myScale = scaleFactory.getScale();

然后,我可以在ScaleFactory中使用autowired属性来定义scaleImplClass。但这似乎很奇怪,因为我的工厂也是服务,而且我有该工厂的一个实例。

-

另一种方法是Class scaleImplementationClass在我的 服务中
而不是ScaleFacotry中拥有该属性,并像下面这样使用ScaleFactory:

@Value("${scaleImplementationClass}")
Class scaleImplementationClass

...

Scale myScale = ScaleFactory.getScale(scaleImplementationClass);

但是那工厂毫无意义,因为我也可以经营得好scaleImplementationClass.newInstance()


问题答案:

有两种不同的类似Spring的方式可以处理此问题。我个人追求的方法看起来像这样:

public interface ScaleFactory {

    public Scale newInstance();
    public String type();

}

public class FirstScaleFactory implements ScaleFactory {

    public Scale newInstance() {
        return new FirstScale();
    }

    public String type() {
        return "first";
    }

}

public class SecondScaleFactory implements ScaleFactory {

    public Scale newInstance() {
        return new SecondScale();
    }

    public String type() {
        return "second";
    }

}

public class ScaleManager {

    private final Map<String, ScaleFactory> factories;

    @Autowired
    public ScaleManager(List<ScaleFactory> factories) {
        this.factories = factories.stream()
            .collect(Collectors.toMap(f -> f.type(), Function::identity));
    }

    public Scale newInstance(String type) {
        return Optional.ofNullable(factories.get(type))
            .map(factory -> factory.newInstance())
            .orElseThrow(IllegalArgumentException::new);
    }

}

使用这种方法,您ScaleManager可以成为标准的Spring
bean,可以将其连接到任何需要scale实例的类中。在初始化时,它将获取ScaleFactoriesSpring上下文中定义的所有内容,并将它们自动连接为List<ScaleFactory>,然后将其转换为a
Map(其中ScaleFactory类型为键)。这样可以避免担心的类名Scale,并且可以稍后更改它们(只要您保持type键的一致性)。

ScaleFactory然后,您的实现可以执行他们需要做的任何事情。例如,如果您拥有一种Scale不可变的类型,则可以让工厂每次都返回相同的实例。另外,您可以让每个调用返回一个单独的实例-
实例化Scale取决于实现的工厂。



 类似资料:
  • 如果我想在用户未登录的情况下阻止应用程序的每个请求,我应该定义哪个.antMatchers()?我知道我必须为登录页面定义antMatchers(“/resources/**”).permitall()以获取css和图像。但是像“/uidl/**”这样的模式是什么呢?我需要它们做什么呢?

  • -- 我想创建一个工厂,就像抽象工厂模式一样,我可以调用,以获得我在Spring XML中配置的任何实现的规模: 但是,使用这种方法,我如何配置ScaleFactory应该使用Spring XML中的哪个实现呢? -- 另一种方法是在我的服务中使用属性而不是ScaleFacotry,并使用ScaleFactory,如下所示: 但是这个工厂就毫无意义了,因为我还可以运行。

  • 本文向大家介绍Spring Boot集成MyBatis实现通用Mapper的配置及使用,包括了Spring Boot集成MyBatis实现通用Mapper的配置及使用的使用技巧和注意事项,需要的朋友参考一下 什么是通用Mapper 通用Mapper就是为了解决单表增删改查,基于Mybatis的插件。开发人员不需要编写SQL,不需要在DAO中增加方法,只要写好实体类,就能支持相应的增删改查方法。 关

  • 本文向大家介绍spring boot配置ssl实现HTTPS的方法,包括了spring boot配置ssl实现HTTPS的方法的使用技巧和注意事项,需要的朋友参考一下 传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Sockets Layer,缩写作 SSL)是一种安全协议,目的是为互联网通信,提供安全及数据完整性保障。

  • 问题内容: 我是Spring的新手,想将spring ioc连接到我的小型(测试)网络应用程序中。 我有这样的Servlet : 和我的web.xml: 而且我也有这样的Spring配置XML: 我有这样的问题: 我希望在servlet init()期间将requestHelper对象设置为我的servlet。但除了这个,它还给了我nullpointer。 我正在尝试从实现servlet ,将其写

  • 我的应用程序。yml: 在使用URL:http://localhost:8888/movie/default时,我在file:///e:/idea/spring-cloud-microservice-example-master/config-microservice/src/main/resources/configPath中发现错误:java.lang.IllegalStateExceptio