an important aspect of cdi is the type-safe injection including type-safe qualifiers and many other concepts based on type-safety.
"surprisingly" type-safe concepts get ignored quite often when it comes to accessing config-values.
however, there is no technical limitation here. in fact creating even generic approaches for type-safe configs can be easy once the implementation is based on deltaspike.
-> like with many other topics my answer is something like:
"use deltaspike and it's way easier."
in case of config-approaches, deltaspike provides several flexible and extensible concepts.
e.g. the upcoming chapter of http://cdiatwork.irian.at will also describe some of them in detail.
beyond that it's easy to implement your own concepts based on mechanisms provided by deltaspike.
the following listing illustrates how to implement your own type-safe config.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@PartialBeanBinding | |
@Retention(RUNTIME) | |
@Target(TYPE) | |
public @interface TypeSafeConfig { | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@TypeSafeConfig | |
public class TypeSafeConfigHandler implements java.lang.reflect.InvocationHandler { | |
public Object invoke(Object o, Method method, Object[] args) throws Throwable { | |
String key = method.getName(); | |
String value = ConfigResolver.getProjectStageAwarePropertyValue(key); | |
return parseValue(method.getReturnType(), value); | |
} | |
private Object parseValue(Class<?> type, String value) { | |
//... | |
} | |
} |
with those two simple classes, we can create custom type-safe configs by just creating interfaces and annotating them with our own binding-annotation (see @TypeSafeConfig). the following listings show two examples how to define and use such a custom config (see AppConfig and BatchConfig).
the last snippet shows how to inject and use both configs in any cdi-bean. in the illustrated example we use them in CustomBatchStarter, which is a cdi-enabled implementation of org.quartz.Job (see @org.apache.deltaspike.scheduler.api.Scheduled).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//example #1 for a custom type-safe config | |
@TypeSafeConfig | |
public interface AppConfig { | |
String name(); | |
ApplicationVersion version(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//example #2 for a custom type-safe config | |
@TypeSafeConfig | |
public interface BatchConfig { | |
Integer numberOfRetries(); | |
Long batchSize(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//example for injecting and using type-safe configs | |
@Scheduled(cronExpression = "0 0/10 * * * ?") | |
public class CustomBatchStarter implements org.quartz.Job { | |
@Inject | |
private LogService logService; | |
@Inject | |
private AppConfig appConfig; | |
@Inject | |
private BatchConfig batchConfig; | |
@Inject | |
private CustomBatchService batchService; | |
@Override | |
public void execute(JobExecutionContext context) throws JobExecutionException { | |
logService.log(appConfig.name(), appConfig.version(), | |
getClass().getName() + " started"); | |
batchService.start(batchConfig.batchSize()); | |
} | |
} |