Use services as “factories” to return different bean implementations… here is a solution to the problem.
Use services as “factories” to return different bean implementations
I want to use this type of service class as a “factory” in my Spring application to return the correct implementation of DocumentProcessor in response to the provided enumeration value.
I
did this because I wanted to set up each processor itself as a component and take advantage of Autowiring instead of just creating new instances when each processor was needed.
I haven’t really seen this done anywhere else – can anyone tell me if this is a bad idea?
All TypeXYZDocumentProcessor classes are extensions of the abstract “DocumentProcessor” base class.
@Service
public class DocumentProcessorService {
@Autowired
TypeXDocumentProcessor typeXDocumentProcessor;
@Autowired
TypeYDocumentProcessor typeYDocumentProcessor;
@Autowired
TypeZDocumentProcessor typeZDocumentProcessor;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
switch (docType) {
case TYPE_X:
return typeXDocumentProcessor;
case TYPE_Y:
return typeYDocumentProcessor;
case TYPE_Z:
return typeZDocumentProcessor;
default:
return null;
}
}
}
@Component
public class TypeXDocumentProcessor extends DocumentProcessor {
...
}
public abstract class DocumentProcessor {
...
}
Solution
This is my proposal, I used an interface instead of an abstract class, but if you really need an abstract class, you can return it.
@Service
public class DocumentProcessorService {
@Autowired
you can add here for examlpe a @Qualifier("typeXDocumentProcessor"),
then name your variable whatever you want.
DocumentProcessor typeXDocumentProcessor;
@Autowired
DocumentProcessor typeYDocumentProcessor;
@Autowired
DocumentProcessor typeZDocumentProcessor;
public DocumentProcessor getDocumentProcessor(DocumentType docType) {
switch (docType) {
case TYPE_X:
return typeXDocumentProcessor;
case TYPE_Y:
return typeYDocumentProcessor;
case TYPE_Z:
return typeZDocumentProcessor;
default:
return null;
}
}
}
@Component
public class TypeXDocumentProcessor implements DocumentProcessor {
...
}
@Component
public class TypeYDocumentProcessor implements DocumentProcessor {
...
}
@Component
public class TypeZDocumentProcessor implements DocumentProcessor {
...
}
public interface class DocumentProcessor {
...
}