官术网_书友最值得收藏!

CDI for Java SE 8

The 2.0 version does not mark the start of using CDI in SE, as that support was already provided in a non-standard way. Both Apache OpenWebBeans and Weld did support the SE mode, and these have been standardized now for use with CDI in Java SE. There are also other projects that support CDI such as Apache DeltaSpike, which offers portable extensions that are handy features for Java developers.

To get started, you can create a Maven project and declare a dependency on a CDI implementation such as JBoss Weld. If Maven isn’t your cup of tea, you can use other means to get the weld-se-core library added to your standalone SE project. Your pom.xml should have a dependency declaration, as shown here:

<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se-core</artifactId>
<version>3.0.0.Final</version>
</dependency>

Additionally, create a beans.xml file located under src/main/resources/META-INF/, with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd"
bean-discovery-mode="all">
</beans>

From an API perspective, this library provides an implementation of CDI 2.0, and its basic dependency graph is shown here for a maven project named cdi2-se-app (a few additional dependencies have not been shown to keep it simple):

With the weld-se-core library added, we can now begin writing a CDI powered application.

Let’s look at some sample code of the CDI in action:

public class BootCDI {   
public void doSomething() {
System.out.println("do something called");
}

public static void main(String... args) {
try (SeContainer container = SeContainerInitializer
.newInstance().initialize()) {
BootCDI appInstance = container
.select(BootCDI.class)
.get();
appInstance.doSomething();
}
}
}

The SeContainerInitializer.newInstance().initialize() call starts up the CDI container. This returns an SeContainer instance, which is our handle to the CDI container. This class also allows for some basic looking up of beans without having to go through the underlying BeanManager. As we used try-with-resources, the container resource will be closed at the end of the try block.

The select method on the SeContainer instance will obtain the BootCDI bean instance in a type-safe manner by returning an Instance<BootCDI> object, which is further used to get the dynamically returned object of BootCDI type. That’s all it takes to boot up CDI in your SE application in a standard way.

The SeContainerInitializer.newInstance() also allows programmatic configuration by invoking methods such as addPackages and disableDiscovery to restrict the runtime behavior to only look for classes that you are interested in, without having to work with beans.xml. There are more possibilities that can be configured by exploring the APIs of the Weld container, allowing for a highly configurable environment. Dependency injection itself can be achieved by simply using @Inject in the code for the dependency. The annotation can be used on method, constructor, and field. This allows setter, constructor, and field injection support respectively.

We can now use classes such as Task with annotations, binding them to well-defined contexts such as ApplicationScoped, SessionScoped, or RequestScoped. The Task class in turn can use a constructor-based dependency on TaskPersistence, which will be injected by the CDI. The scope of TaskPersistence will be bound to the scope of the Task bean. If Task is declared as ApplicationScoped, then the dependency of TaskPersistence is bound to the scope of Task, which is the owning object in this situation. Thus, multiple calls to retrieve the Task bean would return the same Task instance along with the same TaskPersistence object as its dependency. Here's what the refactored Task using the CDI looks like:

class TaskPersistence { 
//Code omitted for brevity
}

@ApplicationScoped
public class Task {
private final TaskPersistence persistence;

@Inject Task(TaskPersistence persistence) {
this.persistence = persistence;
}
//Rest of the code omitted for brevity
...
}

If an application code directly uses the new operator to instantiate a bean, then no parameters or dependencies are injected for that bean and its life cycle is not managed by the container.

主站蜘蛛池模板: 吉首市| 克什克腾旗| 邵阳市| 长丰县| 长泰县| 太仓市| 桐柏县| 濉溪县| 如东县| 娱乐| 镇原县| 甘泉县| 威远县| 金川县| 开封县| 遵义县| 上思县| 肥乡县| 韶山市| 印江| 来安县| 晋宁县| 明水县| 大渡口区| 丰原市| 太原市| 德庆县| 罗平县| 汉中市| 加查县| 叙永县| 长寿区| 汝城县| 苍溪县| 犍为县| 大方县| 开阳县| 石门县| 乐陵市| 广水市| 武汉市|