0
votes

I have to implement a instance factory, that return a new message handler instance depend on message code.

There is a interface MessageHandler and about 50 implementations of this interface. Because of project structure (maven cyclic dependencies...) the factory class has no dependencies to concrete interface implementations.

A messageHandler interface:

interface MessageHandler {
    void receive(Message message);

    MessageCode getMessageCode();
}

Every MessageHandler implementation returns a unique message code. For example:

class FirstMessageHandler implements MessageHandler {
     ...
     @Override
     MessageCode getMessageCode(){
          return MessageCodes.MESSAGE_TYPE_ONE;
     }
     ...
}

class SecondMessageHandler implements MessageHandler {
     ...
     @Override
     MessageCode getMessageCode(){
          return MessageCodes.MESSAGE_TYPE_TWO;
     }
     ...
}

The MessageHandlerFactory should create new handler instance for every message. The factory has no information about concrete implementations and has no dependencies to the maven packages of the implementations. It has only the messageCodes.

class MessagehandlerFactory {
       MessageHandler createHandler(MessageCode messageCode){
       ...
       }
}

After searching i found a examples about @Produce annotation and this nice example:

http://docs.oracle.com/javaee/6/tutorial/doc/gkgkv.html

But in this example, i need to know all implementation types in the factory and this is not allowed.

Actually solution is to use @Any @Instance.

 @Inject
 @Any
 private Instance<MessageHandler> messageHandlers;

@PostConstruct
public void init() {
    for (MessageHandler handler : messageHandlers) {
        messageHandlerMap.put(handler.getMessageCodes(), handler);
    }
}

but this code create for every message instances of all MessageHandler implementations for every received message. It is possible to combine @Produce and @Qualifier so that only one MessageHandler instance will be created depend on received MessageCode?

I am using Glassfish 3.1.2.2.

2

2 Answers

2
votes

You can get all the instances in a portable extension by observing ProcessAnnotatedType. Store those off in a either another class or a static collection on the listener class, then you can get all those instances by injecting the class.

Another option is inject the InjectionPoint into your producer method and use the information there to return the instance you need during your Instance traversal. Note, however, this will only work for dependent scoped injections.

0
votes

Not sure I understand your functional requirement.

Sounds like the producer pattern is the wrong choice, if you don't know what to produce then why go with it?

I dont follow what the code will actually do, but let me ask you whats wrong with just having the interface and make implementations?

Every new implementation gets it's own qualifier and any contextual instance can use @Inject @QualifierName to get it.

I actually think you might be doing things complicated for no reason but I'm not sure since I don't really understand the question :-)