CDI ContextResolver Pattern 2.0
What is the ContextResolver Pattern?
It is a pattern describe by Sven Ruppert (here) to solve the following problem.
The Problem
A service has several implementations which are provided to clients depending on a specific environment context (for example: test- or developmentcontext) on the service side. The client does not know about the context and the environment context must be dynamically configurable.
The Solution
Decouple the service creation from the context resolving by introducing
The Evolution
The previous version is implemented with CDI extensions which is a little bit harder to understand and needs a javax.enterprise.inject.spi.Extension file. So here is the improved version which uses only plain CDI-Producers and therefore should be easier to understand.
The client:
The producer:
The ContextResolver:
The ManagedBeanCreator:
It is a pattern describe by Sven Ruppert (here) to solve the following problem.
The Problem
A service has several implementations which are provided to clients depending on a specific environment context (for example: test- or developmentcontext) on the service side. The client does not know about the context and the environment context must be dynamically configurable.
The Solution
Decouple the service creation from the context resolving by introducing
- a ContextResolver which determines the current context and returns an annotation literal
- a Service Context Qualifier
- a service producer which uses the servicecontextqualifier
The previous version is implemented with CDI extensions which is a little bit harder to understand and needs a javax.enterprise.inject.spi.Extension file. So here is the improved version which uses only plain CDI-Producers and therefore should be easier to understand.
The client:
@Inject @DemoLogicContext Instance<DemoLogic> demoLogicInst;
The producer:
public class DemoLogicProducer { @Produces @DemoLogicContext public DemoLogic create(BeanManager beanManager, @Any Instance<ContextResolver> contextResolvers) { return ManagedBeanCreator.createManagedInstance(beanManager, contextResolvers, DemoLogic.class); } }
The ContextResolver:
public class DemoLogicContextResolver implements ContextResolver { @Inject Context context; @Override public AnnotationLiteral<?> resolveContext(Class<?> targetClass) { //Determines the context and returns annotionliteral return context.isUseB() ? new MandantB.Literal() : new MandantA.Literal(); } }
The ManagedBeanCreator:
public class ManagedBeanCreator { public static <T> T createManagedInstance(BeanManager beanManager, Instance<ContextResolver> contextResolvers, Class<? extends T> clazz) { //FindFirst for (ContextResolver contextResolver : contextResolvers) { AnnotationLiteral<?> annotationLiteral = contextResolver.resolveContext(DemoLogic.class); Set<Bean<?>> beans = beanManager.getBeans(clazz, annotationLiteral); //Create CDI Managed Bean Bean<?> bean = beans.iterator().next(); CreationalContext<?> ctx = beanManager.createCreationalContext(bean); return (T) beanManager.getReference(bean, clazz, ctx); } return null; } }
The sources can be found here.Have fun coding.
Kommentare
Kommentar veröffentlichen