Download as pdf or txt
Download as pdf or txt
You are on page 1of 42

CDIDependencyInjectionAnIntroductoryJavaEETutorial

Part1
(/users/39319/rhightower.html)byRickHightower(/users/39319/rhightower.html)Mar.28,11JavaZone(/javajdkdevelopmenttutorialstools
news)

Like(4)

Comment(31)

Save

Tweet

233.6kViews

TheJavaZoneisbroughttoyouinpartnershipwithJetBrains(/go?
i=106823&u=http%3A%2F%2Fblog.jetbrains.com%2Fkotlin%2F2015%2F11%2Fthekotlinlanguage10betais
here%2F%3Futm_source%3Ddzonejava%26utm_medium%3Dpromo
link%26utm_content%3Dlanguage_matters%26utm_campaign%3Dkotlin).LearnmoreaboutKotlin(/go?
i=106823&u=http%3A%2F%2Fblog.jetbrains.com%2Fkotlin%2F2015%2F11%2Fthekotlinlanguage10betais
here%2F%3Futm_source%3Ddzonejava%26utm_medium%3Dpromo
link%26utm_content%3Dlanguage_matters%26utm_campaign%3Dkotlin),anewprogramminglanguagedesignedbyJetBrainstosolve
problemsthatsoftwaredevelopersfaceeveryday.

CDI(http://jcp.org/aboutJava/communityprocess/final/jsr299/index.html)istheJavastandardfordependencyinjection(DI)and
interception(AOP).ItisevidentfromthepopularityofDIandAOPthatJavaneedstoaddressDIandAOPsothatitcanbuildother
standardsandJSRsontopofit.DIandAOParethefoundationofmanyJavaframeworks,andCDIwillbethefoundationofmanyfuture
specificationsandJSRs.
Thisarticlediscussesdependencyinjectioninatutorialformat.ItcoverssomeofthefeaturesofCDIsuchastypesafeannotations
configuration,alternativesandmore.Thistutorialissplitintotwoparts,thefirstpartcoversthebasisofdependencyinjection,@Inject,
@Producesand@Qualifiers.ThenextpartinthisseriescoversadvancedtopicslikecreatingpluggablecomponentswithInstanceand
processingannotationsforconfiguration.
CDIisafoundationalaspectofJavaEE6.ItisorwillbeshortlysupportedbyCaucho'sResin(http://www.caucho.com/resin/),IBM's
WebSphere,Oracle'sGlassfish(http://glassfish.java.net/),RedHat'sJBoss(http://www.jboss.org/jbossas/docs/6x.html)andmany
moreapplicationservers.CDIissimilartocoreSpringandGuiceframeworks.LikeJPAdidforORM,CDIsimplifiesandsanitizesthe
APIforDIandAOP.IfyouhaveworkedwithSpringorGuice,youwillfindCDIeasytouseandeasytolearn.Ifyouarenewto
DependencyInjection(DI),thenCDIisaneasyonrampforpickingupDIquickly.CDIissimplertouseandlearn.
CDIcanbeusedstandaloneandcanbeembeddedintoanyapplication.
Sourcecodeforthistutorial(https://jee6cdi.googlecode.com/svn/tutorial/cdidiexample),andinstructions
(http://code.google.com/p/jee6cdi/wiki/MavenDITutorialInstructions)foruse.
ItisnoaccidentthatthistutorialfollowsthisSpring2.5DItutorial(usingSpring"new"DIannotations)(/articles/dependencyinjection
anintrod)writtenthreeyearsago.Itwillbeinterestingtocompareandcontrasttheexamplesinthistutorialwiththeonewrittenthree
yearsagoforSpringDIannotations.

Designgoalsofthistutorial

ThistutorialseriesismeanttobeadescriptionandexplanationofDIinCDIwithouttheclutterofEJB3.1orJSF.Therearealready
plentyoftutorialsthatcoverEJB3.1andJSFwithCDIasasupportingactor.
CDIhasmeritonitsownoutsideoftheEJBandJSFspace.ThistutorialonlycoversCDI.RepeatthereisnoJSF2orEJB3.1inthis
tutorial.ThereareplentyofarticlesandtutorialsthatcoverusingCDIaspartofalargerJEE6application
(http://download.oracle.com/javaee/6/tutorial/doc/gjbnr.html).Thistutorialisnotthat.ThistutorialseriesisCDIandonlyCDI.
Thistutorialonlyhasfull,completecodeexampleswithsourcecodeyoucandownloadandtryoutonyourown.Therearenocode
snippetswhereyoucan'tfigureoutwhereinthecodeyouaresupposetobe.
Westartoutslow,stepbystepandbasic.Thenonceyouunderstandthefundamentals,wepickupthepacequiteabit.
Allcodeexampleshaveactuallybeenrun.Wedon'ttypeinadhoccode.Ifitdidnotrun,itisnotinourtutorial.Wearenotwingingit.
ThereareclearheadingsforcodelistingssoyoucanusethistutorialasacookbookwhenyouwanttousesomefeatureofCDIDIinthe
future.Thisisacodecentrictutorial.Again,thecodelistingsareintheTOConthewikipage(http://code.google.com/p/jee6
cdi/wiki/DependencyInjectionAnIntroductoryTutorial_Part1)soyoucanfindjustthecodelistingyouarelookingforquicklylikean
indexforacookbook.
Decorators,Extentions,Interceptors,Scopesareoutofscopeforthisfirsttutorial.Expecttheminfuturetutorials.
Ifthistutorialiswellrecievedandwegetenoughfeedbackthrough,theJavaLobbyarticles,ourgooglegroupandcommentssectionof
thewikithenwewilladdacomprehensivetutorialonCDIAOP(DecoratorsandInterceptors)andoneonExtentions.Themorepositive
and/orconstructivefeedbackwegetthemoreencouragedwewillbetoaddmore.

DependencyInjection
DependencyInjection(DI)referstotheprocessofsupplyinganexternaldependencytoasoftwarecomponent.DIcanhelpmakeyour
codearchitecturallypure.
Itaidsindesignbyinterfaceaswellastestdrivendevelopmentbyprovidingaconsistentwaytoinjectdependencies.Forexample,adata
accessobject(DAO)maydependonadatabaseconnection.
InsteadoflookingupthedatabaseconnectionwithJNDI,youcouldinjectit.
OnewaytothinkaboutaDIframeworklikeCDIistothinkofJNDIturnedinsideout.Insteadofanobjectlookingupotherobjectsthatit
needstogetitsjobdone(dependencies),aDIcontainerinjectsthosedependentobjects.ThisisthesocalledHollywoodPrinciple,"Don't
callus"(lookupobjects),"we'llcallyou"(injectobjects).
IfyouhaveworkedwithCRC(http://en.wikipedia.org/wiki/Classresponsibilitycollaboration_card)cardsyoucanthinkofa
dependencyasacollaborator.Acollaboratorisanobjectthatanotherobjectneedstoperformitsrole,likeaDAO(dataaccessobject)
needsaJDBCconnectionobjectforexample.

DependencyInjectionAutomatedTellerMachinewithoutCDIorSpringorGuice
Let'ssaythatyouhaveanautomatedtellermachine(ATM,alsoknownasanautomatedbankingmachineinothercountries)anditneeds
theabilitytotalktoabank.Ituseswhatitcallsatransportobjecttodothis.Inthisexample,atransportobjecthandlesthelowlevel
communicationtothebank.
Thisexamplecouldberepresentedbythesetwointerfacesasfollows:

CodeListing:AutomatedTellerMachineinterface

1
packageorg.cdi.advocacy;

packageorg.cdi.advocacy;
2

3
importjava.math.BigDecimal;
4

5
publicinterfaceAutomatedTellerMachine{
6

7
publicabstractvoiddeposit(BigDecimalbd);
8

9
publicabstractvoidwithdraw(BigDecimalbd);
10

11
}

CodeListing:ATMTransportinterface

1
packageorg.cdi.advocacy;
2

3
publicinterfaceATMTransport{
4
publicvoidcommunicateWithBank(byte[]datapacket);
5
}

NowtheAutomatedTellerMachineneedsatransporttoperformitsintent,namelywithdrawmoneyanddepositmoney.Tocarryout
thesetasks,theAutomatedTellerMachinemaydependonmanyobjectsandcollaborateswithitsdependenciestocompletethework.
AnimplementationoftheAutomatedTellerMachinemaylooklikethis:

CodeListing:AutomatedTellerMachineImplclass

1
packageorg.cdi.advocacy;
2
...
3
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
4

5
privateATMTransporttransport;
6

7
...
8
publicvoiddeposit(BigDecimalbd){
9
System.out.println("depositcalled");
10
transport.communicateWithBank(...);
11
}
12

13
publicvoidwithdraw(BigDecimalbd){
14
System.out.println("withdrawcalled");
15
transport.communicateWithBank(...);
16
}
17

18
}

TheAutomatedTellerMachineImpldoesnotknoworcarehowthetransportwithdrawsanddepositsmoneyfromthebank.This
levelofindirectionallowsustoreplacethetransportwithdifferentimplementationssuchasinthefollowingexample:

Threeexampletransports:SoapAtmTransport,StandardAtmTransportandJsonAtmTransport

CodeListing:StandardAtmTransport

1
packageorg.cdi.advocacy;
2

4
publicclassStandardAtmTransportimplementsATMTransport{
5

6
publicvoidcommunicateWithBank(byte[]datapacket){
7
System.out.println("communicatingwithbankviaStandardtransport");
8
...
9
}
10

11
}

CodeListing:SoapAtmTransport

1
packageorg.cdi.advocacy;
2

3
publicclassSoapAtmTransportimplementsATMTransport{
4

5
publicvoidcommunicateWithBank(byte[]datapacket){
6
System.out.println("communicatingwithbankviaSoaptransport");
7
...
8
}
9

10
}

CodeListing:JsonRestAtmTransport

1
packageorg.cdi.advocacy;
2

3
publicclassJsonRestAtmTransportimplementsATMTransport{
4

5
publicvoidcommunicateWithBank(byte[]datapacket){
6
System.out.println("communicatingwithbankviaJSONRESTtransport");
7
}
8

9
}

NoticethepossibleimplementationsoftheATMTransportinterface.TheAutomatedTellerMachineImpldoesnotknoworcare
whichtransportituses.Also,fortestinganddeveloping,insteadoftalkingtoarealbank,youcouldeasilyuseMockito
(http://mockito.org/)orEasyMock(http://easymock.org/)oryoucouldevenwriteaSimulationAtmTransportthatwasamock
implementationjustfortesting.
TheconceptofDItranscendsCDI,GuiceandSpring.Thus,youcanaccomplishDIwithoutCDI,GuiceorSpringasfollows:

CodeListing:AtmMain:DIwithoutCDI,SpringorGuice

1
packageorg.cdi.advocacy;
2

3
publicclassAtmMain{
4

5
publicvoidmain(String[]args){
6
AutomatedTellerMachineatm=newAutomatedTellerMachineImpl();
7
ATMTransporttransport=newSoapAtmTransport();
8
/*Injectthetransport.*/
9
((AutomatedTellerMachineImpl)atm).setTransport(transport);
10

11
atm.withdraw(newBigDecimal("10.00"));
12

13
atm.deposit(newBigDecimal("100.00"));
14
}
15

16
}

Theninjectingadifferenttransportisamerematterofcallingadifferentsettermethodasfollows:

CodeListing:AtmMain:DIwithoutCDI,SpringorGuice:setTransport

1
ATMTransporttransport=newSimulationAtmTransport();
2
((AutomatedTellerMachineImpl)atm).setTransport(transport);

TheaboveassumesweaddedasetTransportmethodtotheAutomateTellerMachineImpl.Noteyoucouldjustaseasilyuse
constructorargumentsinsteadofasettermethod.ThuskeepingtheinterfaceofyourAutomateTellerMachineImplclean.

Runningtheexamples
Toruntheexamplesquickly,wesetupsomemavenpom.xmlfilesforyou.Herearetheinstructions(http://code.google.com/p/jee6
cdi/wiki/MavenDITutorialInstructions)togettheexamplesupandrunning.

DependencyInjectionAutomatedTellerMachineusingCDI
TouseCDItomanagethedependencies,dothefollowing:
1.Createanemptybean.xmlfileunderMETAINFresourcefolder
2.Usethe@InjectannotationtoannotateasetTransportsettermethodinAutomatedTellerMachineImpl
3.Usethe@DefaultannotationtoannotatetheStandardAtmTransport
4.Usethe@AlternativetoannotatetheSoapAtmTransport,andJsonRestAtmTransport.
5.Usethe@NamedannotationtomaketheAutomatedTellerMachineImpleasytolookupgiveitthename"atm"
6.UsetheCDIbeanContainertolookuptheatm,makessomedepositsandwithdraws.

Step1:Createanemptybean.xmlfileunderMETAINFresourcefolder

METAINF/beans.xml

CDIneedsanbean.xmlfiletobeinMETAINFofyourjarfileorclasspathorWEBINFofyourwebapplication.Thisfilecanbe
completelyempty(asin0bytes).Ifthereisnobeans.xmlfileinyourMETAINForWEBINFthenthatwarfileorjarfilewillnotbe
processedbyCDI.Otherwise,CDIwillscanthejarandwarfileifthebeans.xmlfileexistsevenifitis0bytes.

CodeListing:METAINF/beans.xmljustasemptyascanbe

1
<beansxmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
2
xsi:schemaLocation="
3
http://java.sun.com/xml/ns/javaee
4
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
5

6
</beans>

Noticethatweincludedastarterbeans.xmlfilewithanamespaceanda``element.Althoughbeans.xmlcouldbecompletelyempty,it
isnicetohaveastarterfilesowhenyouneedtoaddthings(likelateroninthistutorial)youcanreadily.AlsoitkeepstheIDEfrom
complainingaboutillformedxmlwhenyouactuallydohavea0bytebeans.xml.(IhatewhentheIDEcomplains.Itisverydistracting.)

Step2:Usethe@InjectannotationtoannotateasetTransportsettermethodinAutomatedTellerMachineImpl

The@Injectannotationisusedtomarkwhereaninjectiongoes.Youcanannotateconstructorarguments,instancefieldsandsetter
methodsofproperties.Inthisexample,wewillannotatethesetTransportmethod(whichwouldbethesettermethodofthetransport
property).

CodeListing:AutomatedTellerMachineImplusing@Injecttoinjectatransport

1
packageorg.cdi.advocacy;
2

3
...
4

5
importjavax.inject.Inject;
6

7
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
8

9
privateATMTransporttransport;
10

11
@Inject
12
publicvoidsetTransport(ATMTransporttransport){
13
this.transport=transport;
14
}
15

16
...
17

18
}

Continuereading...Clickonthenavigationlinksbelowtheauthorbiotoreadtheotherpagesofthisarticle.
BesuretocheckoutpartIIofthisseriesaswell:Part2pluginsandannotationprocessing(/articles/cdidip2)!

Abouttheauthor

ThisarticlewaswrittenwithCDIadvocacyinmindbyRickHightower(http://profiles.google.com/RichardHightower/about)withsome
collaborationfromothers.RickHightowerhasworkedasaCTO,DirectorofDevelopmentandaDeveloperforthelast20years.Hehas
beeninvolvedwithJ2EEsinceitsinception.HeworkedatanEJBcontainercompanyin1999.HehasbeenworkingwithJavasince1996,
andwritingcodeprofessionallysince1990.RickwasanearlySpringenthusiast(http://java.syscon.com/node/47735).Rickenjoys
bouncingbackandforthbetweenC,Python,GroovyandJavadevelopment.
AlthoughnotafanofEJB3(http://java.syscon.com/node/216307),RickisabigfanofthepotentialofCDIandthinksthatEJB3.1has
comealotclosertothemark.

comealotclosertothemark.
RickHightower(http://profiles.google.com/RichardHightower/about)isCTOofMammatus(http://www.mammatustech.com/)andis
anexpertonJavaandCloudComputing(http://cloud.mammatustech.com/).RickisinvovledinJavaCDIadvocacyandJavaEE.CDI
ImplementationsResinCandi(http://www.caucho.com/)SeamWeld(http://seamframework.org/Weld)ApacheOpenWebBeans
(http://openwebbeans.apache.org/1.1.0SNAPSHOT/index.html)
Bydefault,CDIwouldlookforaclassthatimplementstheATMTransportinterface,onceitfindsthisitcreatesaninstanceandinjects
thisinstanceofATMTransportusingthesettermethodsetTransport.IfweonlyhadonepossibleinstanceofATMTransportinour
classpath,wewouldnotneedtoannotateanyoftheATMTransportimplementations.Sincewehavethree,namely,
StandardAtmTransport,SoapAtmTransport,andJsonAtmTransport,weneedtomarktwoofthemas@Alternative'sand
oneas@Default.

Step3:Usethe@DefaultannotationtoannotatetheStandardAtmTransport

Atthisstageoftheexample,wewouldlikeourdefaulttransporttobeStandardAtmTransportthus,wemarkitas@Defaultas
follows:

CodeListing:StandardAtmTransportusing@Default

1
packageorg.cdi.advocacy;
2

3
importjavax.enterprise.inject.Default;
4

5
@Default
6
publicclassStandardAtmTransportimplementsATMTransport{
7
...

Itshouldbenotedthataclassis@Defaultbydefault.Thusmarkingitsoisredundantandnotonlythatitsredundant.

Step4:Usethe@AlternativetoannotatetheSoapAtmTransport,andJsonRestAtmTransport.

Ifwedon'tmarktheothersas@Alternative,theyarebydefaultasfarasCDIisconcerned,markedas@Default.Let'smark
JsonRestAtmTransportandSoapRestAtmTransport@AlternativesoCDIdoesnotgetconfused.

CodeListing:JsonRestAtmTransportusing@Alternative

1
packageorg.cdi.advocacy;
2

3
importjavax.enterprise.inject.Alternative;
4

5
@Alternative
6
publicclassJsonRestAtmTransportimplementsATMTransport{
7

8
...
9
}

CodeListing:SoapAtmTransportusing@Alternative

1
packageorg.cdi.advocacy;
2

3
importjavax.enterprise.inject.Alternative;
4

5
@Alternative
6
publicclassSoapAtmTransportimplementsATMTransport{
7
...
8
}

Step5:Usethe@NamedannotationtomaketheAutomatedTellerMachineImpleasytolookupgiveitthename"atm"

SincewearenotusingAutomatedTellerMachineImplfromaJavaEE6application,let'sjustusethebeanContainertolookitup.
Let'sgiveitaneasylogicalnamelike"atm".Togiveitaname,usethe@Namedannotation.The@Namedannotationisalsousedby
JEE6applicationtomakethebeanaccessibleviatheUnifiedEL(http://java.sun.com/products/jsp/reference/techart/unifiedEL.html)
(ELstandsforExpressionlanguageanditgetsusedbyJSPsandJSFcomponents).
Hereisanexampleofusing@NamedtogivetheAutomatedTellerMachineImplthename"atm"asfollows:

CodeListing:AutomatedTellerMachineImplusing@Named

1
packageorg.cdi.advocacy;
2

3
importjava.math.BigDecimal;
4

5
importjavax.inject.Inject;
6
importjavax.inject.Named;
7

8
@Named("atm")
9
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
10
...
11

12
}

Itshouldbenotedthatifyouusethe@Namedannotationsanddon'tprovideaname,thenthenameisthenameoftheclasswiththe

Itshouldbenotedthatifyouusethe@Namedannotationsanddon'tprovideaname,thenthenameisthenameoftheclasswiththe
firstletterlowercasesothis:
1
@Named
2
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
3
...
4

5
}

makesthenameautomatedTellerMachineImpl.

Step6:UsetheCDIbeanContainertolookuptheatm,makessomedepositsandwithdraws.

LastlywewanttolookuptheatmusingthebeanContainerandmakesomedeposits.

CodeListing:AtmMainlookinguptheatmbyname

1
packageorg.cdi.advocacy;
2

3
...
4

5
publicclassAtmMain{
6

7
...
8
...
9

10
publicstaticvoidmain(String[]args)throwsException{
11
AutomatedTellerMachineatm=(AutomatedTellerMachine)beanContainer

12
.getBeanByName("atm");
13

14
atm.deposit(newBigDecimal("1.00"));
15

16
}
17

18
}

Whenyourunitfromthecommandline,youshouldgetthefollowing:
Output
1
depositcalled
2
communicatingwithbankviaStandardtransport

YoucanalsolookuptheAtmMainbytypeandanoptionallistofAnnotationsasthenameisreallytosupporttheUnifiedEL(JSPs,JSF,
etc.).

CodeListing:AtmMainlookinguptheatmbytype

1
packageorg.cdi.advocacy;
2

3
...
4

5
publicclassAtmMain{

7
...
8
...
9

10
publicstaticvoidmain(String[]args)throwsException{
11
AutomatedTellerMachineatm=beanContainer.getBeanByType(AutomatedTellerMachine.class);
12
atm.deposit(newBigDecimal("1.00"));
13
}
14

15
}

SinceabigpartofCDIisitstypesafeinjection,lookingupthingsbynameisprobablydiscouraged.Noticewehaveonelesscastdueto
JavaGenerics(http://download.oracle.com/javase/tutorial/java/generics/index.html).
Ifyouremovethe@DefaultfromtheStandardATMTransport,youwillgetthesameoutput.Ifyouremovethe@Alternativefrom
bothoftheothertransports,namely,JsonATMTransport,andSoapATMTransport,CDIwillcroakasfollows:
Output
1
Exceptioninthread"main"java.lang.ExceptionInInitializerError
2
Causedby:javax.enterprise.inject.AmbiguousResolutionException:org.cdi.advocacy.AutomatedTellerMachineImpl.setTransport:
3
Toomanybeansmatch,becausetheyallhaveequalprecedence.
4
Seethe@Stereotypeand<enable>tagstochooseaprecedence.Beans:
5
ManagedBeanImpl[JsonRestAtmTransport,{@Default(),@Any()}]
6
ManagedBeanImpl[SoapAtmTransport,{@Default(),@Any()}]
7
ManagedBeanImpl[StandardAtmTransport,{@javax.enterprise.inject.Default(),@Any()}]
8

8
...

CDIexpectstofindoneandonlyonequalifiedinjection.Laterwewilldiscusshowtouseanalternative.

Using@Injecttoinjectviaconstructorargsandfields
Youcaninjectintofields,constructorargumentsandsettermethods(oranymethodreally).
Hereisanexampleoffieldinjections:

CodeListing:AutomatedTellerMachineImpl.transportusing@Injecttodofieldinjection.

1
...
2
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
3

4
@Inject
5
privateATMTransporttransport;

Continuereading...Clickonthenavigationlinksbelowtheauthorbiotoreadtheotherpagesofthisarticle.
BesuretocheckoutpartIIofthisseriesaswell:Part2pluginsandannotationprocessing(/articles/cdidip2)!

Abouttheauthor

ThisarticlewaswrittenwithCDIadvocacyinmindbyRickHightower(http://profiles.google.com/RichardHightower/about)withsome
collaborationfromothers.RickHightowerhasworkedasaCTO,DirectorofDevelopmentandaDeveloperforthelast20years.Hehas
beeninvolvedwithJ2EEsinceitsinception.HeworkedatanEJBcontainercompanyin1999.HehasbeenworkingwithJavasince1996,
andwritingcodeprofessionallysince1990.RickwasanearlySpringenthusiast(http://java.syscon.com/node/47735).Rickenjoys
bouncingbackandforthbetweenC,Python,GroovyandJavadevelopment.
AlthoughnotafanofEJB3(http://java.syscon.com/node/216307),RickisabigfanofthepotentialofCDIandthinksthatEJB3.1has
comealotclosertothemark.
RickHightower(http://profiles.google.com/RichardHightower/about)isCTOofMammatus(http://www.mammatustech.com/)andis
anexpertonJavaandCloudComputing(http://cloud.mammatustech.com/).RickisinvovledinJavaCDIadvocacyandJavaEE.CDI

ImplementationsResinCandi(http://www.caucho.com/)SeamWeld(http://seamframework.org/Weld)ApacheOpenWebBeans
(http://openwebbeans.apache.org/1.1.0SNAPSHOT/index.html)

CodeListing:AutomatedTellerMachineImpl.transportusing@Injecttodoconstructorinjection.

1
...
2
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
3

4
@Inject
5
publicAutomatedTellerMachineImpl(ATMTransporttransport){
6
this.transport=transport;
7
}

Thisflexibilityallowsyoutocreateclassesthatareeasytounittest.

Usingsimple@Produces
Therearetimeswhenthecreationofanobjectmaybecomplex.Insteadofrelyingonaconstructor,youcandelegatetoafactoryclassto
createtheinstance.TodothiswithCDI,youwouldusethe@Producesfromyourfactoryclassasfollows:

CodeListing:TransportFactory.createTransportusing@Producestodefineafactorymethod

1
packageorg.cdi.advocacy;
2

3
importjavax.enterprise.inject.Produces;
4

5
publicclassTransportFactory{
6

7
@ProducesATMTransportcreateTransport(){
8
System.out.println("ATMTransportcreatedwithproducer");
9
returnnewStandardAtmTransport();
10
}
11

12
}

Thefactorymethodcouldusequalifiersjustlikeaclassdeclaration.Inthisexample,wechosenotto.The
AutomatedTellerMachineImpldoesnotneedtospecifyanyspecialqualifiers.HereistheAutomatedTellerMachineImplthat
receivesthesimpleproducer.

CodeListing:AutomatedTellerMachineImplreceivesthesimpleproducer

1
importjavax.inject.Inject;
2
importjavax.inject.Named;
3

4
@Named("atm")
5
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
6

7
@Inject
8
privateATMTransporttransport;
9
...

CheckyourunderstandingbylookingattheoutputofrunningthiswithAtmMain.
Output
1
ATMTransportcreatedwithproducer
2
depositcalled
3
communicatingwithbankviaStandardtransport

Using@AlternativetoselectanAlternative
Earlier,youmayrecall,wedefinedseveralalternativetransports,namely,JsonRestAtmTransportandSoapRestAtmTransport.
ImaginethatyouareaninstallerofATMmachinesandyouneedtoconfigurecertaintransportsatcertainlocations.Ourprevious
injectionpointsessentiallyinjectthedefaultwhichistheStandardRestAtmTransporttransport.
IfIneedtoinstalladifferenttransport,allIneedtodoischangethe/METAINF/beans.xmlfiletousetherighttransportasfollows:

CodeListing:{classpath}/METAINF/beans.xml

1
<beansxmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
2
xsi:schemaLocation="
3
http://java.sun.com/xml/ns/javaee
4
http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
5
<alternatives>
6
<class>org.cdi.advocacy.JsonRestAtmTransport</class>
7
</alternatives>
8
</beans>

YoucanseefromtheoutputthattheJSONRESTtransportisselected.
Output
1

depositcalled
2
communicatingwithbankviaJSONRESTtransport

AlternativescodifiesandsimplifiesaverynormalcaseinDI,namely,youhavedifferentinjectedobjectsbasedondifferentbuildsor
environments.Thegreatthingaboutobjectsistheycanbereplaced(GradyBoochsaidthis).Alternativesallowyoutomarkobjectsthat
arereplacementsforotherobjectsandthenactivatethemwhenyouneedthem.
IftheDIcontainercanhavealternatives,let'smarkthemasalternatives.Thinkaboutitthisway.Idon'thavetodocumentallofthe
alternativesasmuch.Itisselfdocumenting.IfsomeoneknowsCDIandtheyknowaboutAlternativestheywillnotbesurprised.
AlternativesreallycanonicalizesthewayyouselectanAlternative.
YoucanthinkofCDIasacanonicalizationofmanypatternsthatwehavebeenusingwithmoregeneralpurposeDIframeworks.The
simplificationandcanonicalizationispartoftheevolutionofDI.

CodeListing:Using@Qualifiertoinjectdifferenttypes
AllobjectsandproducersinCDIhavequalifiers.Ifyoudonotassignaqualifieritbydefaulthasthequalifier@Defaultand@Any.Itis
likeaTVcrimeshowintheU.S.,ifyoudonothavemoneyforalawyer,youwillbeassignedone.
Qualifierscanbeusedtodiscriminateexactlywhatgetsinjected.Youcanwritecustomqualifiers.
Qualifiersworklikegaranimal(http://www.garanimals.com/about.htm)tagsforkidsclothes,youmatchthequalifierfromtheinjection
targetandtheinjectionsource,thenthatisthetypethatwillbeinjected.
Ifthetags(Qualifiers)match,thenyouhaveamatchforinjection.
YoumaydecidethatattimesyouwanttoinjectSoaporJsonortheStandardtransport.Youdon'twanttolistthemasanalternative.
Youactually,forexample,alwayswanttheJsonimplementationinacertaincase.
HereisanexampleofdefiningaqualifierforSoap.

CodeListing:Soapruntimequalifierannotation

1
packageorg.cdi.advocacy;
2

3
importjava.lang.annotation.Retention;
4
importjava.lang.annotation.Target;
5
importstaticjava.lang.annotation.ElementType.*;
6
importstaticjava.lang.annotation.RetentionPolicy.*;
7

8
importjavax.inject.Qualifier;
9

10

11
@Qualifier@Retention(RUNTIME)@Target({TYPE,METHOD,FIELD,PARAMETER})
12
public@interfaceSoap{
13

14
}

Noticethataqualifierisjustaruntimeannotationthatismarkedwiththe@Qualifierannotation.The@Qualifierisanannotation
thatdecoratesaruntimeannoationtomakeitaqualifier.
Thenwewouldjustmarkthesourceoftheinjectionpoint,namely,SoapAtmTransportwithournew@Soapqualifierasfollows:

CodeListing:SoapAtmTransportusingnew@Soapqualifier

1
packageorg.cdi.advocacy;
2

3
@Soap
4
publicclassSoapAtmTransportimplementsATMTransport{
5

6
@Override
7
publicvoidcommunicateWithBank(byte[]datapacket){
8
System.out.println("communicatingwithbankviaSoaptransport");
9
}
10

11

NexttimeyouarereadytoinjectaSoaptransportwecandothatbyannotatingtheargumenttotheconstructorasfollows:

CodeListing:AutomatedTellerMachineImplinjectingSoapAtmTransportusingnew@Soapqualifierviaconstructorarg
(/)

/JavaZone(/javajdkdevelopmenttutorialstoolsnews)

publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{

OveramilliondevelopershavejoinedDZone.SignIn/Join

REFCARDZ(/REFCARDZ) GUIDES(/GUIDES) ZONES(/PORTALS) | AGILE(/AGILEMETHODOLOGYTRAININGTOOLSNEWS)


BIGDATA(/BIGDATAANALYTICSTUTORIALSTOOLSNEWS) CLOUD(/CLOUDCOMPUTINGTUTORIALSTOOLSNEWS)
3
privateATMTransporttransport;
4

5
@Inject
6
publicAutomatedTellerMachineImpl(@SoapATMTransporttransport){
7
this.transport=transport;
8
}

Youcouldalsochoosetodothisviathesettermethodforthepropertyasfollows:

CodeListing:AutomatedTellerMachineImplinjectingSoapAtmTransportusingnew@Soapqualifierviasettermethodarg
1
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
2

3
privateATMTransporttransport;
4

5
@Inject
6

6
publicvoidsetTransport(@SoapATMTransporttransport){
7
this.transport=transport;
8
}

Continuereading...Clickonthenavigationlinksbelowtheauthorbiotoreadtheotherpagesofthisarticle.

BesuretocheckoutpartIIofthisseriesaswell:Part2pluginsandannotationprocessing(/articles/cdidip2)!

Abouttheauthor

ThisarticlewaswrittenwithCDIadvocacyinmindbyRickHightower(http://profiles.google.com/RichardHightower/about)withsome
collaborationfromothers.RickHightowerhasworkedasaCTO,DirectorofDevelopmentandaDeveloperforthelast20years.Hehas
beeninvolvedwithJ2EEsinceitsinception.HeworkedatanEJBcontainercompanyin1999.HehasbeenworkingwithJavasince1996,
andwritingcodeprofessionallysince1990.RickwasanearlySpringenthusiast(http://java.syscon.com/node/47735).Rickenjoys
bouncingbackandforthbetweenC,Python,GroovyandJavadevelopment.
AlthoughnotafanofEJB3(http://java.syscon.com/node/216307),RickisabigfanofthepotentialofCDIandthinksthatEJB3.1has
comealotclosertothemark.
RickHightower(http://profiles.google.com/RichardHightower/about)isCTOofMammatus(http://www.mammatustech.com/)andis
anexpertonJavaandCloudComputing(http://cloud.mammatustech.com/).RickisinvovledinJavaCDIadvocacyandJavaEE.CDI
ImplementationsResinCandi(http://www.caucho.com/)SeamWeld(http://seamframework.org/Weld)ApacheOpenWebBeans
(http://openwebbeans.apache.org/1.1.0SNAPSHOT/index.html)
Andaverycommonoptionistouseafieldlevelinjectionasfollows:

CodeListing:AutomatedTellerMachineImplinjectingSoapAtmTransportusingnew@Soapqualifierviasettermethodarg

1
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
2

3
@Inject@Soap
4
privateATMTransporttransport;

Fromthispointon,wearejustgoingtousefieldlevelinjectiontosimplifytheexamples.

Using@Qualfierstoinjectmultipletypesintothesamebeanusing
Let'ssaythatourATMmachineusesdifferenttransportbasedonsomebusinessrulesthatareconfiguredinLDAPorconfigfileorXML

Let'ssaythatourATMmachineusesdifferenttransportbasedonsomebusinessrulesthatareconfiguredinLDAPorconfigfileorXML
oradatabase(doesnotreallymatter).
Thepointisyouwantitdecidedatruntimewhichtransportwearegoingtouse.
Inthisscenariowemaywanttoinjectthreedifferenttransportsandthenconfigureatransportbasedonthebusinessrules.
YouaregoingtowanttogetnotifiedwhentheinjectionisdoneandthebeanisreadytogofromaCDIperspective.Togetthisnotifcation
youwouldannotatedaninitmethodwiththe@PostConstructannotation.Thenyoucouldpickwhichtypeoftransportthatyouwantto
use.
Notethenameofthemethoddoesnotmatter,itistheannotationthatmakesitaninitmethod.

CodeListing:AutomatedTellerMachineImplinjectingmultipletransportsusingnewmultiplequalifiers

1
packageorg.cdi.advocacy;
2

3
importjava.math.BigDecimal;
4

5
importjavax.annotation.PostConstruct;
6
importjavax.inject.Inject;
7
importjavax.inject.Named;
8

9
@Named("atm")
10
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
11

12
privateATMTransporttransport;
13

14
@Inject@Soap
15
privateATMTransportsoapTransport;
16

17
@Inject@Json
18
privateATMTransportjsonTransport;
19

20
@Inject@Json
21
privateATMTransportstandardTransport;
22

23

24
//ThesecouldbelookedupinaDB,JNDIorapropertiesfile.
25
privatebooleanuseJSON=true;
26
privatebooleanbehindFireWall=true;
27

28
@PostConstruct
29
protectedvoidinit(){
30
//LookupvaluesforuseJSONandbehindFireWall
31

32
if(!behindFireWall){
33
transport=standardTransport;
34
}else{
35
if(useJSON){
36
transport=jsonTransport;
37
}else{
38
transport=soapTransport;
39
}
40
}
41

42
}
43

44

45
publicvoiddeposit(BigDecimalbd){
46
System.out.println("depositcalled");
47

48

49
transport.communicateWithBank(null);
50
}
51

52
...
53
}

Trytofollowthecodeabove.Trytoguesstheoutput.Nowcompareittothis:Output
1
depositcalled
2
communicatingwithbankviaJSONRESTtransport

Howdidyoudo?

Using@Producertomakeadecisionaboutcreation
Thisexamplebuildsonthelast.
PerhapsyouwanttoseperatetheconstructionandselectionofthetransportsfromtheAutomatedTellerMachineImpl.
YoucouldcreateaProducerfactorymethodthatmakesadecisionaboutthecreationandselectionofthetransportasfollows:

CodeListing:TransportFactorydecidingwhichtransporttouse/create

1
packageorg.cdi.advocacy;
2

3
importjavax.enterprise.inject.Produces;
4

5
publicclassTransportFactory{
6

7
privatebooleanuseJSON=true;
8
privatebooleanbehindFireWall=true;
9

10

11
@ProducesATMTransportcreateTransport(){
12
//LookupconfigparametersinsomeconfigfileorLDAPserverordatabase
13

14
System.out.println("ATMTransportcreatedwithproducermakesdecisions");

System.out.println("ATMTransportcreatedwithproducermakesdecisions");
15

16
if(behindFireWall){
17
if(useJSON){
18
System.out.println("CreatedJSONtransport");
19
returnnewJsonRestAtmTransport();
20
}else{
21
System.out.println("CreatedSOAPtransport");
22
returnnewSoapAtmTransport();
23
}
24
}else{
25
System.out.println("CreatedStandardtransport");
26
returnnewStandardAtmTransport();
27
}
28
}
29

30
}

Theadvantageofthisapproachisthatthelogictodothecreation,isseparatefromtheactualAutomatedTellerMachineImplcode.
Thismaynotalwaysbewhatyouwant,butifitis,thentheproducercanhelpyou.
Theoutputshouldbethesameasbefore.
Output
1
ATMTransportcreatedwithproducermakesdecisions
2
CreatedJSONtransport
3
depositcalled
4
communicatingwithbankviaJSONRESTtransport

Using@Producerthatusesqualifierstomakeadecisionaboutcreation
Thisexamplebuildsonthelast.
Youcanalsoinjectitemsasargumentsintotheproducerasfollows:

CodeListing:TransportFactoryinjectingqualifierargs

1
packageorg.cdi.advocacy;
2

3
importjavax.enterprise.inject.Produces;
4

5
publicclassTransportFactory{
6

7
privatebooleanuseJSON=true;
8
privatebooleanbehindFireWall=true;
9

10

11
@ProducesATMTransportcreateTransport(@SoapATMTransportsoapTransport,
12
@JsonATMTransportjsonTransport){
13
//Lookupconfigparametersinsomeconfigfile
14
System.out.println("ATMTransportcreatedwithproducermakesdecisions");
15

16
if(behindFireWall){
17
if(useJSON){
18
System.out.println("returnpassedJSONtransport");
19
returnjsonTransport;
20
}else{
21
System.out.println("returnpassedSOAPtransport");
22
returnsoapTransport;
23
}
24
}else{
25
System.out.println("CreateStandardtransport");
26
returnnewStandardAtmTransport();
27
}
28
}
29

30
}

Intheaboveexample,createTransportbecomeslessofafactorymethodandmoreofaselectionmethodasCDIactuallycreatesand
passesthesoapTransportandthejsonTransport.
Advancedtopic:(Ignorethisifitdoesnotmakesense)YoumaywonderwhyIcreateStandardAtmTransportandnotinjectitasa
producerargumentlikesoapTransportandjsonTransport.TheproblemisthiscreateTransportisbydefault@Defaultand
@AnybutitoverridestheStandardAtmTransportwhichisalsobydefault@Defaultand@Any,butsince
StandardAtmTransportisoveriddenthenifIinject@DefaultATMTransportstandardTransportasanargumentthenittriesto
callcreateTransportsinceitisthe@Default,whichwillthentrytoinjecttheargumentstandardTransport,whichwillthencall
createTransport,adinfinitumuntilwegetaStackTraceOverflow.Thesolutioniscreateaqualifierforthestandard,say,
@Standardandusethattodotheinjection,orcreateoneforthecreateProducesproduction,say,@Transport.Thekeyhereisthat
theinjectionargumentsofaproducerhavetohavedifferentqualifiersthantheproductionmethodorallhellbreakslose,catssleeping
withdogs,pandimodium.Ok.Okay.Thekeyhereisthattheinjectionargumentshavetohavedifferentqualifiersthantheproduction
methodoryouwillgetaStackTraceOverflowasCDIcallsyourproductionmethodtoresovletheinjectionpointofyouproduction
methodadinfinitum.
Hereistheexpectedoutput.
Output
1
ATMTransportcreatedwithproducermakesdecisions
2
returnpassedJSONtransport
3
depositcalled
4
communicatingwithbankviaJSONRESTtransport

Usingmultiple@Qualifiersatthesameinjectionpointtodiscriminatefurther
Youcanusemorethanoneqaulifiertofurtherdiscriminateyourinjectiontarget.
Todemonstratethislet'sdefinetoqualifiersSuperFastandStandardFrameRelaySwitchingFlubber.Let'ssayatthetimewehave
twotransportsthatareStandardFrameRelaySwitchingFlubber.Let'salsosaythatyouwanttoinjectatransportthatisnotonlya
StandardFrameRelaySwitchingFlubberbutalsoSuperFast.
Firstlet'sdefinethequalifierannotationsasfollows:

CodeListing:SuperFastdefininganewqualifier

1
packageorg.cdi.advocacy;

3
...
4

5
@Qualifier@Retention(RUNTIME)@Target({TYPE,METHOD,FIELD,PARAMETER})
6
public@interfaceSuperFast{
7

8
}

CodeListing:StandardFrameRelaySwitchingFlubberdefininganothernewqualifier

1
packageorg.cdi.advocacy;
2

3
...
4

5
@Qualifier@Retention(RUNTIME)@Target({TYPE,METHOD,FIELD,PARAMETER})
6
public@interfaceStandardFrameRelaySwitchingFlubber{
7

8
}

Ok,hereisthecodefortheSuperFastAtmTransportwhichismarkedwithboththe@SuperFastandthe
@StandardFrameRelaySwitchingFlubberqualifiers.

CodeListing:SuperFastAtmTransportusestwoqualifiers

CodeListing:SuperFastAtmTransportusestwoqualifiers

1
packageorg.cdi.advocacy;
2

3
@SuperFast@StandardFrameRelaySwitchingFlubber
4
publicclassSuperFastAtmTransportimplementsATMTransport{
5
publicvoidcommunicateWithBank(byte[]datapacket){
6
System.out.println("communicatingwithbankviatheSuperFasttransport");
7
}
8
}

Continuereading...Clickonthenavigationlinksbelowtheauthorbiotoreadtheotherpagesofthisarticle.
BesuretocheckoutpartIIofthisseriesaswell:Part2pluginsandannotationprocessing(/articles/cdidip2)!

Abouttheauthor

ThisarticlewaswrittenwithCDIadvocacyinmindbyRickHightower(http://profiles.google.com/RichardHightower/about)withsome
collaborationfromothers.RickHightowerhasworkedasaCTO,DirectorofDevelopmentandaDeveloperforthelast20years.Hehas
beeninvolvedwithJ2EEsinceitsinception.HeworkedatanEJBcontainercompanyin1999.HehasbeenworkingwithJavasince1996,
andwritingcodeprofessionallysince1990.RickwasanearlySpringenthusiast(http://java.syscon.com/node/47735).Rickenjoys
bouncingbackandforthbetweenC,Python,GroovyandJavadevelopment.
AlthoughnotafanofEJB3(http://java.syscon.com/node/216307),RickisabigfanofthepotentialofCDIandthinksthatEJB3.1has
comealotclosertothemark.
RickHightower(http://profiles.google.com/RichardHightower/about)isCTOofMammatus(http://www.mammatustech.com/)andis
anexpertonJavaandCloudComputing(http://cloud.mammatustech.com/).RickisinvovledinJavaCDIadvocacyandJavaEE.CDI
ImplementationsResinCandi(http://www.caucho.com/)SeamWeld(http://seamframework.org/Weld)ApacheOpenWebBeans
(http://openwebbeans.apache.org/1.1.0SNAPSHOT/index.html)
Ok,weaddtheStandardFrameRelaySwitchingFlubbertotheStandardAtmTransportaswell.

CodeListing:StandardAtmTransportchangedtouseonequalifier

1
packageorg.cdi.advocacy;
2

4
@StandardFrameRelaySwitchingFlubber@Default
5
publicclassStandardAtmTransportimplementsATMTransport{
6
publicvoidcommunicateWithBank(byte[]datapacket){
7
System.out.println("communicatingwithbankviaStandardtransport");
8
}
9

10
}

NextifIwantmyAutomatedTellerMachineImpltohaveSuperFasttransportwithStandardFrameRelaySwitchingFlubber,I
wouldusebothintheinjectiontargetasfollows:

CodeListing:AutomatedTellerMachineImplchangedtousetwoqualifier

1
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
2

3
@Inject@SuperFast@StandardFrameRelaySwitchingFlubber
4
privateATMTransporttransport;
5
...

Output:
1
depositcalled
2
communicatingwithbankviatheSuperFasttransport

Exercise:Createatransportthatis@SuperFast,@StandardFrameRelaySwitchingFlubberandan@Alternative.Thenusebeans.xmlto
activatethisSuperFast,StandardFrameRelaySwitchingFlubber,Alternativetransport.SendmeyoursolutionontheCDIgroupmailing

activatethisSuperFast,StandardFrameRelaySwitchingFlubber,Alternativetransport.SendmeyoursolutionontheCDIgroupmailing
list(http://groups.google.com/group/cdiadvocate4j?pli=1).ThefirstonetosendgetsputontheCDIwalloffame.
Exerciseforthereader.ChangetheinjectionpointqualifierstomakeonlytheStandardAtmTransportgetinjected.Sendmeyour
solutionontheCDIgroupmailinglist(http://groups.google.com/group/cdiadvocate4j?pli=1).Don'tgetdiscouragedifyougetastack
traceortwothatispartofthelearningprocess.ThefirstonetosendgetsputontheCDIwalloffame(everyoneelsegetsanhonorable
mention).

Using@Qualfierswithmemberstodiscriminateinjectionandstoptheexplosionofannotation
creation
Therecouldbeanexplosionofqualifersannotationsinyourproject.Imagineinourexampleiftherewere20typesoftransports.We
wouldhave20annotationsdefined.
Thisisprobablynotwantyouwant.Itisokayifyouhaveafew,butitcouldquicklybecomeunmanageable.
CDIallowsyoutodescriminateonmembersofaqualifiertoreducetheexplosionofqualifiers.Insteadofhavingthreequalifieryoucould
haveonequalifierandanenum.Thenifyouneedmoretypesoftransports,youonlyhavetoaddanenumvalueinsteadofanotherclass.
Let'sdemonstratehowthisworksbycreatinganewqualifierannotationcalledTransport.TheTransportqualifierannotationwill
haveasinglemember,anenumcalledtype.ThetypememberwillbeannewenumthatwedefinecalledTransportType.
HereisthenewTransportType:

CodeListing:Transportqualifierthathasanenummember

1
packageorg.cdi.advocacy;
2

3
importjava.lang.annotation.Retention;
4
importjava.lang.annotation.Target;
5
importstaticjava.lang.annotation.ElementType.*;
6
importstaticjava.lang.annotation.RetentionPolicy.*;
7

8
importjavax.inject.Qualifier;
9

10

11
@Qualifier@Retention(RUNTIME)@Target({TYPE,METHOD,FIELD,PARAMETER})
12
public@interfaceTransport{
13
TransportTypetype()defaultTransportType.STANDARD;

TransportTypetype()defaultTransportType.STANDARD;
14
}

HereisthenewenumthatispartoftheTransportType.

CodeListing:TransportTypeenumthatdefinesatype

1
packageorg.cdi.advocacy;
2

3
publicenumTransportType{
4
JSON,SOAP,STANDARD;
5
}

Nextyouneedtoqualifyyourtransportinstanceslikeso:

CodeListing:SoapAtmTransportusing*`@Transport(type=TransportType.SOAP)`*

1
packageorg.cdi.advocacy;
2

4
@Transport(type=TransportType.SOAP)
5
publicclassSoapAtmTransportimplementsATMTransport{
6
...

CodeListing:StandardAtmTransportusing*`@Transport(type=TransportType.STANDARD)`*

1
packageorg.cdi.advocacy;
2

3
@Transport(type=TransportType.STANDARD)
4
publicclassStandardAtmTransportimplementsATMTransport{
5
...

CodeListing:JsonRestAtmTransportusing*`@Transport(type=TransportType.JSON)`*

1
packageorg.cdi.advocacy;
2

3
@Transport(type=TransportType.JSON)
4
publicclassJsonRestAtmTransportimplementsATMTransport{
5
...

CodeListing:AutomatedTellerMachineImplusing@Inject*`@Transport(type=TransportType.STANDARD)`*

1
@Named("atm")
2
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
3

4
@Inject@Transport(type=TransportType.STANDARD)

@Inject@Transport(type=TransportType.STANDARD)
5
privateATMTransporttransport;

Asalways,youwillwanttoruntheexample.
Output
1
depositcalled
2
communicatingwithbankviaStandardtransport

Continuereading...Clickonthenavigationlinksbelowtheauthorbiotoreadtheotherpagesofthisarticle.
BesuretocheckoutpartIIofthisseriesaswell:Part2pluginsandannotationprocessing(/articles/cdidip2)!

Abouttheauthor

ThisarticlewaswrittenwithCDIadvocacyinmindbyRickHightower(http://profiles.google.com/RichardHightower/about)withsome
collaborationfromothers.RickHightowerhasworkedasaCTO,DirectorofDevelopmentandaDeveloperforthelast20years.Hehas
beeninvolvedwithJ2EEsinceitsinception.HeworkedatanEJBcontainercompanyin1999.HehasbeenworkingwithJavasince1996,
andwritingcodeprofessionallysince1990.RickwasanearlySpringenthusiast(http://java.syscon.com/node/47735).Rickenjoys
bouncingbackandforthbetweenC,Python,GroovyandJavadevelopment.
AlthoughnotafanofEJB3(http://java.syscon.com/node/216307),RickisabigfanofthepotentialofCDIandthinksthatEJB3.1has
comealotclosertothemark.
RickHightower(http://profiles.google.com/RichardHightower/about)isCTOofMammatus(http://www.mammatustech.com/)andis
anexpertonJavaandCloudComputing(http://cloud.mammatustech.com/).RickisinvovledinJavaCDIadvocacyandJavaEE.CDI
ImplementationsResinCandi(http://www.caucho.com/)SeamWeld(http://seamframework.org/Weld)ApacheOpenWebBeans
(http://openwebbeans.apache.org/1.1.0SNAPSHOT/index.html)
Youcanhavemorethanonememberofthequalifierannotationasfollows:

CodeListing:Transportqualifierannotationwithmorethanonemember

1
packageorg.cdi.advocacy;
2

3
importjava.lang.annotation.Retention;
4
importjava.lang.annotation.Target;
5
importstaticjava.lang.annotation.ElementType.*;
6
importstaticjava.lang.annotation.RetentionPolicy.*;
7

8
importjavax.inject.Qualifier;
9

10

11
@Qualifier@Retention(RUNTIME)@Target({TYPE,METHOD,FIELD,PARAMETER})
12
public@interfaceTransport{
13
TransportTypetype()defaultTransportType.STANDARD;
14
intpriorityLevel()default1;
15
}

NowCDIisgoingtousebothofthememberstodiscriminateforinjection.
Ifwehadatransportlikeso:

CodeListing:AutomatedTellerMachineImplusingtwoqualifiermemberstodiscriminate

1
publicclassAutomatedTellerMachineImplimplementsAutomatedTellerMachine{
2

3
@Inject@Transport(type=TransportType.STANDARD,priorityLevel=1)
4
privateATMTransporttransport;

Thenwegetthis:
Output
1
depositcalled
2
communicatingwithbankviatheSuperFasttransport

communicatingwithbankviatheSuperFasttransport

Youcanmatchusinganytypesupportedbyannotations,e.g.,Strings,classes,enums,ints,etc.
Exercise:AddamemberStringtothequalifierannotation.Changetheinjectionpointtodiscriminateusingthisnewstringmember.Why
doyouthinkthisiscountertowhatCDIstandsfor?SendmeyoursolutionontheCDIgroupmailinglist
(http://groups.google.com/group/cdiadvocate4j?pli=1).ThefirstonetosendgetsputontheCDIwalloffame.(Allothersgethonorable
mentions.)

Conclusion
DependencyInjection(DI)referstotheprocessofsupplyinganexternaldependencytoasoftwarecomponent.
CDI(http://jcp.org/aboutJava/communityprocess/final/jsr299/index.html)istheJavastandardfordependencyinjectionand
interception(AOP).ItisevidentfromthepopularityofDIandAOPthatJavaneedstoaddressDIandAOPsothatitcanbuildother
standardsontopofit.DIandAOParethefoundationofmanyJavaframeworks.IhopeyousharemyvisionofCDIasabasisforother
JSRs,Javaframeworksandstandards.
ThisarticlediscussedCDIdependencyinjectioninatutorialformat.ItcoverssomeofthefeaturesofCDIsuchastypesafeannotations
configuration,alternativesandmore.Therewasanintroductionlevelandandadvacnedlevel.
CDIisafoundationalaspectofJavaEE6.ItisorwillbeshortlysupportedbyCaucho'sResin,IBM's!WebSphere,Oracle'sGlassfish,Red
Hat'sJBossandmanymoreapplicationservers.CDIissimilartocoreSpringandGuiceframeworks.HoweverCDIisageneralpurpose
frameworkthatcanbeusedoutsideofJEE6.
CDIisarethinkonhowtododependencyinjectionandAOP(interceptionreally).Itsimplifiesit.Itreducesit.Itgetsridoflegacy,
outdatedideas.
CDIistoSpringandGuicewhatJPAistoHibernate,andToplink.CDIwillcoexistwithSpringandGuice.Therearepluginstomake
theminteroperatenicely.Thereismoreintegrationoptionontheway.
Thisisjustabrieftaste.Thereismoretocome.

Resources
Part2pluginsandannotationprocessing(/articles/cdidip2)
CDIadvocacygroup(http://sites.google.com/site/cdipojo/)
CDIadvocacyblog(http://cdi4jadvocate.blogspot.com/)
CDIadvocacygooglecodeproject(http://code.google.com/p/jee6cdi/)
GooglegroupforCDIadvocacy(http://groups.google.com/group/cdiadvocate4j)
Manisfestoversion1(http://cdi4jadvocate.blogspot.com/2011/03/cdiadvocacy.html)
Weldreferencedocumentation(http://docs.jboss.org/weld/reference/1.1.0.Final/enUS/html/)
CDIJSR299(http://jcp.org/aboutJava/communityprocess/final/jsr299/index.html)
ResinfastandlightCDIandJavaEE6WebProfileimplementation(http://www.caucho.com/resin/)
CDI&JSFPart1IntrobyAndyGibson(http://www.andygibson.net/blog/tutorial/gettingstartedwithjsf20andcdiinjee6
part1/)
CDI&JSFPart2IntrobyAndyGibson(http://www.andygibson.net/blog/tutorial/gettingstartedwithcdipart2injection/)
CDI&JSFPart3IntrobyAndyGibson(http://www.andygibson.net/blog/tutorial/gettingstartedwithjsf20andcdipart3/)

AbouttheAuthor

AbouttheAuthor
ThisarticlewaswrittenwithCDIadvocacyinmindbyRickHightower(https://profiles.google.com/RichardHightower/about)withsome
collaborationfromothers.RickHightowerhasworkedasaCTO,DirectorofDevelopmentandaDeveloperforthelast20years.Hehas
beeninvolvedwithJ2EEsinceitsinception.HeworkedatanEJBcontainercompanyin1999.HehasbeenworkingwithJavasince1996,
andwritingcodeprofessionallysince1990.RickwasanearlySpringenthusiast(http://java.syscon.com/node/47735).Rickenjoys
bouncingbackandforthbetweenC,Python,GroovyandJavadevelopment.AlthoughnotafanofEJB3(http://java.sys
con.com/node/216307),RickisabigfanofthepotentialofCDIandthinksthatEJB3.1hascomealotclosertothemark.
RickHightower(http://profiles.google.com/RichardHightower/about)isCTOofMammatus(http://www.mammatustech.com/)andis
anexpertonJavaandCloudComputing(http://cloud.mammatustech.com/).RickisinvovledinJavaCDIadvocacyandJavaEE.CDI
ImplementationsResinCandi(http://www.caucho.com/)SeamWeld(http://seamframework.org/Weld)ApacheOpenWebBeans
(http://openwebbeans.apache.org/1.1.0SNAPSHOT/index.html)
Thereare53codelistingsinthisarticle

TheJavaZoneisbroughttoyouinpartnershipwithJetBrains(/go?
i=106824&u=https%3A%2F%2Fwww.jetbrains.com%2Fidea%2Fspecials%2Fidea%2Fsmartide.jsp%3Futm_source%3Ddzonejava%26utm_medi
Discoverhowpowerfulstaticcodeanalysisandergonomicdesign(/go?
i=106824&u=https%3A%2F%2Fwww.jetbrains.com%2Fidea%2Fspecials%2Fidea%2Fsmartide.jsp%3Futm_source%3Ddzonejava%26utm_medi
makedevelopmentnotonlyproductivebutalsoanenjoyableexperience.
Topics: JAVA, SPRING, ANT, GUICE, JAVAEE, AOP, CDI, DEPENDENCYINJECTION, SPRINGDI

You might also like