

A gentle introduction to CDI 2.0 in Java SE
source link: https://aboullaite.me/cdi-20-java-se/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Whenever we mention Context and Dependency Injection, we
automatically think about Java EE (Since CDI 1.0 focused strongly on Java EE). But, as you probably know, you don't necessarily need a Java EE (EE4J) application server to enjoy CDI magic. CDI 2.0 allows developers to use the same wiring model in both Java SE and Java EE and introduces new features to make CDI in Java SE more useful.
This blog post shows how to bootstrap CDI 2.0 in Java SE using Weld.
Why adding Java SE support
From the spec we can highlight 3 main reasons:
- Align with many other Java EE spec (JPA, JAX-RS ...) which support Java SE bootstrapping
- Boost CDI adoption for Spec and Frameworks
- Provide a mean of building new stacks out of Java EE
Before CDI 2.0
Using Context Dependency Injection on Java SE applications is something not totally new. Here is how thing could be done using Weld.
First add weld dependency to your pom.xml:
<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.4.6.Final </version>
</dependency>
To activate CDI we need to create a beans archive and include beans.xml
file in the META-INF
directory of the classpath. We add an empty beans.xml file:
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd" >
</beans>
Then we could startup the container with like this:
public static void main(String[] args) throws IOException {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
Application application = container.instance().select(Application.class).get();
application.run();
weld.shutdown();
}
Although that does work, isn't it more accurate to have a standard way to boot CDI containers ?! That's what CDI 2.0 is about.
Bootstrap a CDI 2.0 container
CDI 2.0 introduced SeContainerInitializer
, which is a new api to configure and bootstrap a CDI container under Java SE, it returns a SeContainer
that implements Instance<Object>
allowing programmatic lookup.
SeContainerInitializer initializer = SeContainerInitializer.newInstance();
/** disable discovery and register bean classes manually */
try (SeContainer container = initializer.disableDiscovery().addBeanClasses(MyService.class).initialize()) {
container.select(MyService.class);
}
Notice that we called disableDiscovery()
and manually pre-configures all CDI beans to start the CDI environment without the beans.xml
file.
Also, The SeContainerInitializer
class has a lot of methods to preconfigure you CDI container.
public abstract class SeContainerInitializer {
/** Returns an instance of {@link SeContainerInitializer}. Each call returns a new instance */
public static SeContainerInitializer newInstance() {...}
/** Add provided bean classes to the synthetic bean archive. */
public abstract SeContainerInitializer addBeanClasses(Class<?>... classes);
/** All classes from the packages of the specified classes will be added to the set of bean classes for the synthetic bean archive. */
public abstract SeContainerInitializer addPackages(Class<?>... packageClasses);
/** Packages of the specified classes will be scanned and found classes will be added to the set of bean classes for the synthetic bean archive. */
public abstract SeContainerInitializer addPackages(boolean scanRecursively, Class<?>... packageClasses);
/** All classes from the specified packages will be added to the set of bean classes for the synthetic bean archive. */
public abstract SeContainerInitializer addPackages(Package... packages);
/** All classes from the specified packages will be added to the set of bean classes for the synthetic bean archive. */
public abstract SeContainerInitializer addPackages(boolean scanRecursively, Package... packages);
/** Add extensions to the set of extensions. */
public abstract SeContainerInitializer addExtensions(Extension... extensions);
/** Add extensions to the set of extensions. */
public abstract SeContainerInitializer addExtensions(Class<? extends Extension>... extensions);
/** Add interceptor classes to the list of enabled interceptors for the synthetic bean archive. */
public abstract SeContainerInitializer enableInterceptors(Class<?>... interceptorClasses);
/** Add decorator classes to the list of enabled decorators for the synthetic bean archive. */
public abstract SeContainerInitializer enableDecorators(Class<?>... decoratorClasses);
/** Add alternatives classes to the list of selected alternatives for the synthetic bean archive. */
public abstract SeContainerInitializer selectAlternatives(Class<?>... alternativeClasses);
/** Add alternative stereotype classes to the list of selected alternative stereotypes for the synthetic bean archive. */
public abstract SeContainerInitializer selectAlternativeStereotypes(Class<? extends Annotation>... alternativeStereotypeClasses);
/** Add a configuration property to the container */
public abstract SeContainerInitializer addProperty(String key, Object value);
/** Set all the configuration properties. */
public abstract SeContainerInitializer setProperties(Map<String, Object> properties);
/** By default, the discovery is enabled. However, it's possible to disable the discovery completely so that only the "synthetic" bean archive is considered. */
public abstract SeContainerInitializer disableDiscovery();
/** Set a {@link ClassLoader}. The given {@link ClassLoader} will be scanned automatically for bean archives if scanning is enabled. */
public abstract SeContainerInitializer setClassLoader(ClassLoader classLoader);
/** Initializes a CDI SeContainerInitializer. (Cannot be called within an application server). */
public abstract SeContainer initialize();
}
To get started, check out this complete example on github, using CDI 2.0. Please feel free to comment below for suggestions and remark.
Recommend
-
65
Sometimes data does not make sense until you can look at in a visual form, such as with charts and plots. Being able to quickly visualize your data samples for yourself and others is an important skill both in ap...
-
39
Go 1.11 introduced a new concept of Modules which brings first class support for managing dependency versions and enabling reproducible builds....
-
29
Go 1.11 introduced a new concept of Modules which brings first class support for managing dependency versions and enabling reproducible builds. Go previously had no notion of dependency versions, and it has been a long and arduous road to get wh...
-
58
Applying probabilistic models to data usually involves integrating a complex, multi-dimensional probability distribution. For example, calculating the expectation/mean of a model distribution involves such an integration. Man...
-
54
I have some grim news for the programmers in the audience. This news comes with a silver lining of course. If you are a web developer (or are thinking about teaching yourself web programming), you probably don't...
-
49
Modern computers have the ability to perform multiple operations at the same time. Supported by hardware advancements and smarter operating systems, this feature makes your programs run faster, both in terms of speed of e...
-
33
Hi there! During the first meetup of argentinaR.org -an R user group-
-
26
In this article we’ll cover the basic idea behind symbolic execution, a powerful yet underutilized technique for static program analysis. Using this technique, we can prove that our code obeys certain properties...
-
62
Photo by Markus Spiske “Life is a school of probability~Walter B...
-
12
Observable Event example with CDI 2.0 (Java EE 8) Code source: GitHub With Java EE 8 CDI will receive a maj...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK