Implement a simple factory pattern with Spring 3 annotations

前端 未结 11 2002
旧巷少年郎
旧巷少年郎 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条回答
  •  Happy的楠姐
    2020-12-12 11:23

    Based on solution by Pavel Černý here we can make an universal typed implementation of this pattern. To to it, we need to introduce NamedService interface:

        public interface NamedService {
           String name();
        }
    

    and add abstract class:

    public abstract class AbstractFactory {
    
        private final Map map;
    
        protected AbstractFactory(List list) {
            this.map = list
                    .stream()
                    .collect(Collectors.toMap(NamedService::name, Function.identity()));
        }
    
        /**
         * Factory method for getting an appropriate implementation of a service
         * @param name name of service impl.
         * @return concrete service impl.
    
         */
        public T getInstance(@NonNull final String name) {
            T t = map.get(name);
            if(t == null)
                throw new RuntimeException("Unknown service name: " + name);
            return t;
        }
    }
    

    Then we create a concrete factory of specific objects like MyService:

     public interface MyService extends NamedService {
               String name();
               void doJob();
     }
    
    @Component
    public class MyServiceFactory extends AbstractFactory {
    
        @Autowired
        protected MyServiceFactory(List list) {
            super(list);
        }
    }
    

    where List the list of implementations of MyService interface at compile time.

    This approach works fine if you have multiple similar factories across app that produce objects by name (if producing objects by a name suffice you business logic of course). Here map works good with String as a key, and holds all the existing implementations of your services.

    if you have different logic for producing objects, this additional logic can be moved to some another place and work in combination with these factories (that get objects by name).

提交回复
热议问题