If it were me, I'd do something similar, but not identical, to option 1:
- Read all plugins at startup, storing their headers and a reference to either their class name or an instance (if they're stateless) in a
HashMap
in aRequestFactory
or similarly named utility. You'd also store references to the built-in system protocols in this map. - When a request comes in, make a call to
RequestFactory.getProtocol(String header)
to grab a reference to the protocol that should be used.
Note that if you go this route, you don't need a method in each protocol class that lets you query whether a header is appropriate for it; the factory handles that for you.
Edit
...I just noticed the "at runtime" part of your question, which makes the "at startup" part of my solution a little out of place. New plugins could still be registered into the factory's internal map as they're recognized/loaded; that shouldn't affect the usefulness of this design as a whole.