Java EE CDI Producer方法教程
這是CDI Producer方法的教程。 在CDI中,生產(chǎn)者方法生成一個可以注入的對象。 當我們要注入本身不是bean的對象,要注入的對象的具體類型在運行時可能有所不同,或者當對象需要一些bean構(gòu)造函數(shù)不執(zhí)行的自定義初始化時,可以使用生產(chǎn)者方法。 生產(chǎn)者方法允許我們將任何JDK類公開為bean,并為同一實現(xiàn)類定義具有不同范圍或初始化的多個bean。 他們還讓我們將運行時多態(tài)與CDI結(jié)合使用。
在這里,我們將創(chuàng)建一個具有兩個實現(xiàn)的簡單服務,然后將創(chuàng)建一個Producer方法以在應用程序中生成和注入這兩個實現(xiàn)。
我們首選的開發(fā)環(huán)境是Eclipse 。 我們正在使用Eclipse Juno(4.2)版本以及Maven Integration插件版本3.1.0。 您可以從Eclipse的這里從和Maven Eclipse插件這里 。 用于Eclipse的Maven插件的安裝不在本教程的討論范圍內(nèi),因此將不予討論。 Tomcat 7是使用的應用程序服務器。
讓我們開始,
1.創(chuàng)建一個新的Maven項目
轉(zhuǎn)到文件->項目-> Maven-> Maven項目。
在向?qū)У摹斑x擇項目名稱和位置”頁面中,確保未選中 “創(chuàng)建簡單項目(跳過原型選擇)”選項,單擊“下一步”以繼續(xù)使用默認值。
在這里,必須添加用于創(chuàng)建Web應用程序的Maven原型。 單擊“添加原型”并添加原型。 將“ Archetype組ID”變量設(shè)置為"org.apache.maven.archetypes" ,將“ Archetype構(gòu)件ID”變量設(shè)置為"maven-archetype-webapp" ,將“ Archetype版本”設(shè)置為"1.0" 。 點擊“確定”繼續(xù)。
在向?qū)У摹拜斎牍ぜ蘒D”頁面中,您可以定義項目的名稱和主程序包。 將“ Group Id”變量設(shè)置為"com.javacodegeeks.snippets.enterprise" ,將“ Artifact Id”變量設(shè)置為"cdibeans" 。 上述選擇組成主體工程包作為"com.javacodegeeks.snippets.enterprise.cdibeans"和項目名稱為"cdibeans" 。 將“ Package”變量設(shè)置為"war" ,以便創(chuàng)建一個war文件以部署到tomcat服務器。 點擊“完成”退出向?qū)Р?chuàng)建您的項目。
Maven項目結(jié)構(gòu)如下所示:
- 它包含以下文件夾:
- / src / main / java文件夾,其中包含應用程序動態(tài)內(nèi)容的源文件,
- / src / test / java文件夾包含用于單元測試的所有源文件,
- / src / main / resources文件夾包含配置文件,
- / target文件夾包含已編譯和打包的可交付成果,
- / src / main / resources / webapp / WEB-INF文件夾包含Web應用程序的部署描述符,
- pom.xml是項目對象模型(POM)文件。 包含所有項目相關(guān)配置的單個文件。
2.添加所有必要的依賴項
您可以通過在POM編輯器的“ Pom.xml”頁面上對其進行編輯,來在Maven的pom.xml文件中添加依賴項,如下所示:
pom.xml:
如您所見,Maven以聲明方式管理庫依賴關(guān)系。 創(chuàng)建本地存儲庫(默認情況下,位于{user_home} /。m2文件夾下),所有必需的庫都從公共存儲庫下載并放置在該庫中。 此外,庫內(nèi)的依賴關(guān)系會自動解決和處理。
3.創(chuàng)建一個簡單的服務
在此示例中, Producer將使用的服務是一個簡單的服務,它為使用該服務的應用程序創(chuàng)建問候消息。 GreetingCard.java類是帶有產(chǎn)生問候消息的方法的接口。
GreetingCard.java
package com.javacodegeeks.snippets.enterprise.cdibeans;public interface GreetingCard {void sayHello(); }該服務的實現(xiàn)如下所示:
GreetingCardImpl.java
package com.javacodegeeks.snippets.enterprise.cdibeans.impl;import com.javacodegeeks.snippets.enterprise.cdibeans.GreetingCard;public class GreetingCardImpl implements GreetingCard {public void sayHello() {System.out.println("Hello!!!");}}為了顯示多態(tài)性在CDI中的工作方式,我們將創(chuàng)建該服務的另一個實現(xiàn),如下所示:
AnotherGreetingCardImpl.java
package com.javacodegeeks.snippets.enterprise.cdibeans.impl;import com.javacodegeeks.snippets.enterprise.cdibeans.GreetingCard;public class AnotherGreetingCardImpl implements GreetingCard {public void sayHello() {System.out.println("Have a nice day!!!");}}4.在托管Bean中使用生產(chǎn)者
在下面的托管bean中,我們利用了上面創(chuàng)建的Producer 。 特別是,在GreetingCardFactory.java類中,我們創(chuàng)建了一個方法getGreetingCard() ,該方法帶有@Produces批注。 該方法根據(jù)bean的GreetingType返回GreetingCard的正確實現(xiàn)。 這樣就支持了多態(tài)性。
GreetingCardFactory.java
package com.javacodegeeks.snippets.enterprise.cdibeans;import java.io.Serializable;import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Produces;import com.javacodegeeks.snippets.enterprise.cdibeans.impl.AnotherGreetingCardImpl; import com.javacodegeeks.snippets.enterprise.cdibeans.impl.GreetingCardImpl;@SessionScoped public class GreetingCardFactory implements Serializable {private static final long serialVersionUID = -44416514616012281L;private GreetingType greetingType;@Producespublic GreetingCard getGreetingCard() {switch (greetingType) {case HELLO:return new GreetingCardImpl();case ANOTHER_HI:return new AnotherGreetingCardImpl();default:return new GreetingCardImpl();}} }GreetingType.java是一個枚舉,如下所示:
GreetingType.java
package com.javacodegeeks.snippets.enterprise.cdibeans;public enum GreetingType {HELLO, HI; }在CDI中使用多態(tài)的另一種方法是通過@Qualifier 。 我們可以在CDI中創(chuàng)建自己的注釋,然后在Producer方法中使用它來獲取正確的實現(xiàn)。
Greetings.java
package com.javacodegeeks.snippets.enterprise.cdibeans;import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target;import javax.inject.Qualifier;@Qualifier @Retention(RUNTIME) @Target({ FIELD, TYPE, METHOD }) public @interface Greetings {GreetingType value();}現(xiàn)在, GreetingCardFactory可以為每個實現(xiàn)使用不同的Producer方法。 我們創(chuàng)建的注釋在@Produces注釋之后使用。
GreetingCardFactory.java
package com.javacodegeeks.snippets.enterprise.cdibeans;import java.io.Serializable;import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Produces;import com.javacodegeeks.snippets.enterprise.cdibeans.impl.AnotherGreetingCardImpl; import com.javacodegeeks.snippets.enterprise.cdibeans.impl.GreetingCardImpl;@SessionScoped public class GreetingCardFactory implements Serializable {private static final long serialVersionUID = -44416514616012281L;private GreetingType greetingType;@Produces@Greetings(GreetingType.HELLO)public GreetingCard getGreetingCard() {return new GreetingCardImpl();}@Produces@Greetings(GreetingType.HI)public GreetingCard getAnotherGreetingCard() {return new AnotherGreetingCardImpl();}}5.生產(chǎn)者范圍
創(chuàng)建一個通知時,一個重要的事情Producer方法是范圍Producer 。 默認情況下, Producer的范圍設(shè)置為“ Dependent 。 但是Producer根據(jù)其用途也可以具有任何其他范圍。 問題是,如果Producer生產(chǎn)范圍不同的托管bean,可能會發(fā)生什么。 例如,我們可以使用標注為@SessionScoped的Producer創(chuàng)建一個@RequestScoped bean并將其注入另一個bean。 在這種情況下,HTTP請求完成后, Producer返回的@RequestScoped bean實例將被銷毀,并且注入該bean的行為可能是意外的。 為了避免引用不再存在的bean,在使用Producer方法時,可以使用@New批注。 這樣,將通過Producer注入一個新的Dependent實例,如下面的代碼片段所示:
GreetingCardFactory.java
package com.javacodegeeks.snippets.enterprise.cdibeans;import java.io.Serializable;import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.New; import javax.enterprise.inject.Produces;import com.javacodegeeks.snippets.enterprise.cdibeans.impl.GreetingCardImpl;@SessionScoped public class GreetingCardFactory implements Serializable {private static final long serialVersionUID = -44416514616012281L;private GreetingCardImpl greetingCard;@Producespublic GreetingCardImpl getGreetingCard(@New GreetingCardImpl greetingCard) {return greetingCard;}}6.運行應用程序
為了運行該應用程序,我們創(chuàng)建了一個簡單的servlet,如下所示:
GreetingServlet.java
package com.javacodegeeks.snippets.enterprise.cdibeans.servlet;import java.io.IOException; import java.io.PrintWriter;import javax.inject.Inject; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import com.javacodegeeks.snippets.enterprise.cdibeans.GreetingCard; import com.javacodegeeks.snippets.enterprise.cdibeans.GreetingType; import com.javacodegeeks.snippets.enterprise.cdibeans.Greetings;@WebServlet(name = "greetingServlet", urlPatterns = {"/sayHello"}) public class GreetingServlet extends HttpServlet {private static final long serialVersionUID = 2280890757609124481L;@Inject@Greetings(GreetingType.HELLO)private GreetingCard greetingCard;@Inject@Greetings(GreetingType.HI)private GreetingCard anotherGreetingCard;public void init() throws ServletException {}public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<h1>" + greetingCard.sayHello() + "</h1>");out.println("<h1>" + anotherGreetingCard.sayHello() + "</h1>");}public void destroy(){}}在上面的servlet中,注入了兩種實現(xiàn)。 要運行該示例,我們必須使用Maven構(gòu)建項目,然后將生成的war文件放置在tomcat的webbaps文件夾中。 然后,我們可以繼續(xù):
http://localhost/8080/cdibeans/sayHello
結(jié)果是如下所示:
這是Java EE CDI Producer方法的教程。
下載本教程的源代碼: CDIProducerMethodExample.zip
翻譯自: https://www.javacodegeeks.com/2013/04/java-ee-cdi-producer-methods-tutorial.html
總結(jié)
以上是生活随笔為你收集整理的Java EE CDI Producer方法教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux双屏怎么设置复制(linux
- 下一篇: 最小的JavaFX演示文稿(在JavaF