使用 Spring 3 注解实现一个简单的工厂模式

新手上路,请多包涵

我想知道如何使用 Spring 3 注释实现简单的工厂模式。我在文档中看到您可以创建调用工厂类并运行工厂方法的 bean。我想知道这是否可能仅使用注释。

我有一个当前调用的控制器

MyService myService = myServiceFactory.getMyService(test);
result = myService.checkStatus();

MyService 是一个接口,其中一个方法称为 checkStatus()。

我的工厂类如下所示:

 @Component
public class MyServiceFactory {

    public static MyService getMyService(String service) {
        MyService myService;

        service = service.toLowerCase();

        if (service.equals("one")) {
            myService = new MyServiceOne();
        } else if (service.equals("two")) {
            myService = new MyServiceTwo();
        } else if (service.equals("three")) {
            myService = new MyServiceThree();
        } else {
            myService = new MyServiceDefault();
        }

        return myService;
    }
}

MyServiceOne 类如下所示:

 @Autowired
private LocationService locationService;

public boolean checkStatus() {
      //do stuff
}

当我运行此代码时,locationService 变量始终为空。我相信这是因为我自己在工厂内创建对象并且没有进行自动装配。有没有办法添加注释以使其正常工作?

谢谢

原文由 blong824 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

你是对的,通过手动创建对象,你不会让 Spring 执行自动装配。考虑通过 Spring 管理您的服务:

 @Component
public class MyServiceFactory {

    @Autowired
    private MyServiceOne myServiceOne;

    @Autowired
    private MyServiceTwo myServiceTwo;

    @Autowired
    private MyServiceThree myServiceThree;

    @Autowired
    private MyServiceDefault myServiceDefault;

    public static MyService getMyService(String service) {
        service = service.toLowerCase();

        if (service.equals("one")) {
            return myServiceOne;
        } else if (service.equals("two")) {
            return myServiceTwo;
        } else if (service.equals("three")) {
            return myServiceThree;
        } else {
            return myServiceDefault;
        }
    }
}

但我认为整体设计相当糟糕。 Wouldn’t it better to have one general MyService implementation and pass one / two / three string as extra parameter to checkStatus() ?你想达到什么目标?

 @Component
public class MyServiceAdapter implements MyService {

    @Autowired
    private MyServiceOne myServiceOne;

    @Autowired
    private MyServiceTwo myServiceTwo;

    @Autowired
    private MyServiceThree myServiceThree;

    @Autowired
    private MyServiceDefault myServiceDefault;

    public boolean checkStatus(String service) {
        service = service.toLowerCase();

        if (service.equals("one")) {
            return myServiceOne.checkStatus();
        } else if (service.equals("two")) {
            return myServiceTwo.checkStatus();
        } else if (service.equals("three")) {
            return myServiceThree.checkStatus();
        } else {
            return myServiceDefault.checkStatus();
        }
    }
}

仍然 设计得很糟糕,因为添加新的 MyService 实现还需要 MyServiceAdapter 修改(违反 SRP)。但这实际上是一个很好的起点(提示:地图和策略模式)。

原文由 Tomasz Nurkiewicz 发布,翻译遵循 CC BY-SA 3.0 许可协议

以下对我有用:

该接口由您的逻辑方法和其他身份方法组成:

 public interface MyService {
    String getType();
    void checkStatus();
}

一些实现:

 @Component
public class MyServiceOne implements MyService {
    @Override
    public String getType() {
        return "one";
    }

    @Override
    public void checkStatus() {
      // Your code
    }
}

@Component
public class MyServiceTwo implements MyService {
    @Override
    public String getType() {
        return "two";
    }

    @Override
    public void checkStatus() {
      // Your code
    }
}

@Component
public class MyServiceThree implements MyService {
    @Override
    public String getType() {
        return "three";
    }

    @Override
    public void checkStatus() {
      // Your code
    }
}

工厂本身如下:

 @Service
public class MyServiceFactory {

    @Autowired
    private List<MyService> services;

    private static final Map<String, MyService> myServiceCache = new HashMap<>();

    @PostConstruct
    public void initMyServiceCache() {
        for(MyService service : services) {
            myServiceCache.put(service.getType(), service);
        }
    }

    public static MyService getService(String type) {
        MyService service = myServiceCache.get(type);
        if(service == null) throw new RuntimeException("Unknown service type: " + type);
        return service;
    }
}

我发现这样的实现更容易、更简洁并且更可扩展。添加新的 MyService 就像创建另一个实现相同接口的 spring bean 一样简单,而无需在其他地方进行任何更改。

原文由 DruidKuma 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题