Implement a simple factory pattern with Spring 3 annotations

前端 未结 11 1998
旧巷少年郎
旧巷少年郎 2020-12-12 10:37

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

相关标签:
11条回答
  • 2020-12-12 11:26

    Try this:

    public interface MyService {
     //Code
    }
    
    @Component("One")
    public class MyServiceOne implements MyService {
     //Code
    }
    
    @Component("Two")
    public class MyServiceTwo implements MyService {
     //Code
    }
    
    0 讨论(0)
  • 2020-12-12 11:27

    You could also declaratively define a bean of type ServiceLocatorFactoryBean that will act as a Factory class. it supported by Spring 3.

    A FactoryBean implementation that takes an interface which must have one or more methods with the signatures (typically, MyService getService() or MyService getService(String id)) and creates a dynamic proxy which implements that interface

    Here's an example of implementing the Factory pattern using Spring

    One more clearly example

    0 讨论(0)
  • 2020-12-12 11:27

    Following the answer from DruidKuma and jumping_monkey

    You can also include optional and make your code a bit nicer and cleaner:

     public static MyService getService(String type) {
            return Optional.ofNullable(myServiceCache.get(type))
                    .orElseThrow(() -> new RuntimeException("Unknown service type: " + type));
     }
    
    0 讨论(0)
  • 2020-12-12 11:28

    The following worked for me:

    The interface consist of you logic methods plus additional identity method:

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

    Some implementations:

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

    And the factory itself as following:

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

    I've found such implementation easier, cleaner and much more extensible. Adding new MyService is as easy as creating another spring bean implementing same interface without making any changes in other places.

    0 讨论(0)
  • 2020-12-12 11:29

    I suppose you to use org.springframework.beans.factory.config.ServiceLocatorFactoryBean. It will much simplify your code. Except MyServiceAdapter u can only create interface MyServiceAdapter with method MyService getMyService and with alies to register your classes

    Code

    bean id="printStrategyFactory" class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
            <property name="YourInterface" value="factory.MyServiceAdapter" />
        </bean>
    
        <alias name="myServiceOne" alias="one" />
        <alias name="myServiceTwo" alias="two" />
    
    0 讨论(0)
提交回复
热议问题