@Inject和@Named大家都知道.这篇主要是说自定义注解的使用方式.JBOSS官方有下载的.
faces-config.xml是用于配jsf的.beans.xml是用于cdi的(大多时候它的作用是告诉系统,我是用了CDI,也有一些功能需要用到它).
<faces-config version="2.0" 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/web-facesconfig_2_0.xsd"> </faces-config>
<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>POM文件略.
界面很简单,输出2个:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>cdi-injection</title> </head> <body> <div> English Hello: #{translation.englishHello} <br /> Spanish Hello: #{translation.spanishHello} </div> </body> </html>最终输出图为:
页面使用的后台bean:
package org.jboss.as.quickstarts.cdi.injection.backing; import javax.inject.Inject; import javax.inject.Named; import org.jboss.as.quickstarts.cdi.injection.TranslateService; import org.jboss.as.quickstarts.cdi.injection.qualifier.English; import org.jboss.as.quickstarts.cdi.injection.qualifier.Spanish; /** * Simple JSF backing bean, demonstrating CDI injection and qualifiers. * 简单的JSF backingbean,展示CDI注入和限定符。 * Also note, this bean has a name different than the default name. * 注意Named重新定义了名称. * @author Jason Porter */ @Named("translation") public class TranslationBackingBean { @Inject @Spanish private TranslateService spanishTranslateService; @Inject @English private TranslateService englishTranslateService; public String getSpanishHello() { return spanishTranslateService.hello(); } public String getEnglishHello() { return englishTranslateService.hello(); } }
@Named和@Inject不多做介绍了.
下面是Service接口:
package org.jboss.as.quickstarts.cdi.injection; public interface TranslateService { String hello(); }
两个实现:
@Spanish public class SpanishTranslateService implements TranslateService { @Override public String hello() { return "Hola"; } }
@English public class EnglishTranslateService implements TranslateService { @Override public String hello() { return "Hello"; } }现在的疑问就在@English和@西班牙语了.
package org.jboss.as.quickstarts.cdi.injection.qualifier; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.inject.Qualifier; @Qualifier @Target({ ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER }) @Documented @Retention(RetentionPolicy.RUNTIME) public @interface English { }
在TranslationBackingBean 中,
@Inject @Spanish private TranslateService spanishTranslateService;
这句话就是说,注入使用的TranslateService实现为:西班牙.
@Spanish需要标注在实现里和注入的地方.
使用@Qualifier注入不同的类型
在CDI中所有的对象和生产者都是限定类型的。如果你没有分配限定类型那么将会使用默认的@Default和@Any。就像一个罪犯在美国,如果没有足够的钱给律师,那么他将会被分配一个限定类型用来识别正确的对象被注入,你可以写自己定制的限定类型。
限定类型能够匹配注入目标和注入源,确保正确的类型被注入。
@Retention: 定义注解的保留策略
关于java的注解自定义将重开一篇文章.
页面code:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>CDI Alternative Result</title> </head> <body> The injected value is: <%=request.getAttribute("type")%> </body> </html>Servlet:
package org.jboss.as.quickstarts.cdi.alternative; import java.io.IOException; import javax.inject.Inject; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/") public class Demo extends HttpServlet { private static final long serialVersionUID = 1L; @Inject private Tax tax; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { request.setAttribute("type", tax.getRate()); RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/result.jsp"); dispatcher.forward(request, response); } catch (Exception e) { e.printStackTrace(); } } }interface:
package org.jboss.as.quickstarts.cdi.alternative; public interface Tax { String getRate(); }
两个实现:
package org.jboss.as.quickstarts.cdi.alternative; public class TaxImpl_1 implements Tax { @Override public String getRate() { return "Tax_1 Rate!"; } }
package org.jboss.as.quickstarts.cdi.alternative; import javax.enterprise.inject.Alternative; @Alternative public class TaxImpl_2 implements Tax { @Override public String getRate() { return "Tax_2 Rate! To switch back to the default, go to /META-INF/beans.xml and comment out the 'alternatives' tag"; } }
注意实现2有@Alternative注解.系统默认输出是taxImpl_1的输出.
如果想输出第二个,只需要在bean.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"> <alternatives> <class>org.jboss.as.quickstarts.cdi.alternative.TaxImpl_2</class> </alternatives> </beans>
配置后,将输出2的内容.
主要用于多个接口实现在bean.xml中的实时切换.
当多个版本的bean来实现不同的目的,在开发过程中,通过注入一个限定或其他版本之间切换.而不必更改源代码的应用程序,可以选择在部署时使用的替代品。
替代方案通常用于以下目的,如:
1. 为了处理客户特定的业务逻辑在运行时确定。
2. 要指定Bean的有效期为一个特定的部署方案,例如,特定国家的销售税的法律时,需要针对具体国家的销售税业务逻辑。
3. 用于测试的模拟版本。