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

2022-01-13 00:00:00 annotations factory-pattern spring java

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

I was wondering how I could implement the simple factory pattern with Spring 3 annotations. I saw in the documentation that you can create beans that call the factory class and run a factory method. I was wondering if this was possible using annotations only.

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

I have a controller that currently calls

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

MyService 是一个接口,其中包含一个名为 checkStatus() 的方法.

MyService is an interface with one method called 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 类如下所示:

MyServiceOne class looks like this :

@Autowired
private LocationService locationService;

public boolean checkStatus() {
      //do stuff
}

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

When I run this code the locationService variable is alwasy null. I beleive this is because I am creating the objects myself inside the factory and autowiring is not taking place. Is there a way to add annotations to make this work correctly?

谢谢

推荐答案

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

You are right, by creating object manually you are not letting Spring to perform autowiring. Consider managing your services by Spring as well:

@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;
        }
    }
}

但我认为整体设计相当糟糕.有一个通用的 MyService 实现并传递 one/two/three 字符串作为额外参数不是更好吗checkStatus()?你想达到什么目标?

But I would consider the overall design to be rather poor. Wouldn't it better to have one general MyService implementation and pass one/two/three string as extra parameter to checkStatus()? What do you want to achieve?

@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).但这实际上是一个很好的起点(提示:地图和策略模式).

This is still poorly designed because adding new MyService implementation requires MyServiceAdapter modification as well (SRP violation). But this is actually a good starting point (hint: map and Strategy pattern).

相关文章