2012年2月2日星期四

NetBeans_012:开发JavaEE 6 应用之十二:使用Qualifier依赖注入Bean

实现了同一个Interface的不同POJO类,在使用CDI依赖注入时,在设计时可以使用Inferface类型注入,但是在运行时如何知道使用的到底是哪个实现呢?
这就要用到Qualifiers,Qualifiers预留值有@Default, @Any, @Named, @New。

1. 编写Interface和POJO类
public interface Greeter {
    public String greet(Customer customer);
}

public class NormalGreeter implements Greeter {

    @Override
    public String greet(Customer customer) {
        return "Hello " + customer.getName() + "!";
    }
}

2. 修改TestServlet,增加依赖注入Greeter和相应逻辑
 @Inject
 Greeter greeter;

 String greet = request.getParameter("greet");
 if (greet != null) {
      Customer customer = bean.getCustomers().get(Integer.parseInt(greet));
      out.println(greeter.greet(customer));
 }

3. 访问http://localhost:8080/JavaEE6SampleApp/TestServlet?greet=0

4. 在增加一个实现了Greeter Interface的类:PromotionalGreeter
public class PromotionalGreeter extends NormalGreeter {

    @Override
    public String greet(Customer customer) {
        String greeting = super.greet(customer);
        if (customer.getCreditLimit() >= 100000) {
            return "You are super, thank you very much! " + greeting;
        }
        if (customer.getCreditLimit() >= 50000) {
            return "Thank you very much! " + greeting;
        }
        if (customer.getCreditLimit() >= 25000) {
            return "Thank you! " + greeting;
        }
        return greeting;
    }
}


再访问http://localhost:8080/JavaEE6SampleApp/TestServlet?greet=0就会抛出异常:
Error occurred during deployment: Exception while loading the app : WELD-001409
Ambiguous dependencies for type [Greeter] with qualifiers [@Default] at injection
point [[field] @Inject org.glassfish.samples.TestServlet.greeter]. Possible
dependencies [[Managed Bean [class org.glassfish.samples.PromotionalGreeter] with
qualifiers [@Any @Default], Managed Bean [class
org.glassfish.samples.NormalGreeter] with qualifiers [@Any @Default]]].
这是因为现在又两个Greeter的实现类,默认都是@Default,应用不知道应该用哪个,因此报错。

5. 在PromotionalGreeter类定义上增加@Promotion标注
因为@Promotion不是保留的标注,因此会有黄色灯泡提示,点击灯泡后,会提示“创建限定符Promotion”。
确定后,会生成Promotion类:
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface Promotion {
}

再访问http://localhost:8080/JavaEE6SampleApp/TestServlet?greet=1,应该显示正常了。

6. 修改TestServlet中的 @Inject Greeter greeter;为@Inject @Promotion Greeter greeter;
输出如下,表明这一次使用的是PromotionalGreeter:

没有评论: