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

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.

主站蜘蛛池模板: 吕梁市| 弋阳县| 沙湾县| 香港 | 甘南县| 密山市| 读书| 武汉市| 宜良县| 专栏| 故城县| 泰安市| 新邵县| 浪卡子县| 九台市| 恩施市| 安岳县| 潞西市| 三江| 交口县| 二连浩特市| 文登市| 青田县| 诏安县| 钟祥市| 达孜县| 蒙山县| 江陵县| 文成县| 时尚| 乌鲁木齐市| 班玛县| 松滋市| 和平区| 新津县| 安陆市| 海城市| 犍为县| 新巴尔虎左旗| 泗洪县| 绥芬河市|