@Produces
功能: 制造组件,自定义组件分配
我们先定义好一个接口Tasks.java
以及他的实现类AsyncTask.java , SyncTask.java
。以及一个枚举类TaskType.java
public enum TaskType {
ASYNC,SYNC;
}
然后看一下@Produces
是怎么调用的
@RequestScoped
public class TaskProducers implements Serializable {
TaskType taskType = TaskType.ASYNC;
public TaskProducers() {
System.out.println("TaskProducers constructor called");
}
/**
* change from @RequestScoped to @ApplicationScoped to see what happened.
*
* @TODO why @SessionScoped failed here?
* @param asyncTask async task
* @param syncTask sync task
* @return Task according to TaskType
*/
@Produces
@Preferred
@SessionScoped
public Task getTask(AsyncTask asyncTask, SyncTask syncTask) {
System.out.println("getTask called......");
switch (taskType) {
case ASYNC:
return asyncTask;
case SYNC:
return syncTask;
default:
return null;
}
}
}
大家看到这里@Produces
修饰Task类型
的getTask()
方法,并且添加一个Qualifter: @Preferred
,也就是说produces 也可以通过qualifter来区分。而且大家都知道在CDI中名字并不重要,重要的是组件类型。也就是说getTask()方法可以修改为任意名字。还有就是可被申请的组件需要同过参数的形式注入。
调用组件TaskController.java
@Model
public class TaskController {
@Inject
@Preferred
Task task;
public String sayHello() {
return "hello task:" + task.getName();
}
@PostConstruct
public void init() {
System.out.println("GreetingController post construct......");
}
@PreDestroy
public void destroy() {
System.out.println("GreetingController pre destroy......");
}
}
这样调用的就是Async组件;
介绍其他几个注解:
- @Model = @Name + @RequestScope
- @PostConstruct:初始化组件,功能相当于构造器
- @PreDestory:销毁组件
@Alterntive
功能:修饰备用组件,一旦激活比@Default修饰的权限高
即如果@Alternative
修饰组件,一般是不会被容器访问,但是如果在beans.xml
文件中中激活,那么容器会优先找到这个组件
<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">
<alternatives>
<class>cn.edu.sdut.softlab.FancyGreeting</class>
</alternatives>
</beans>
示例代码:
https://github.com/liuqinyi/weld-tutorial
https://github.com/liuqinyi/quickstart.git