Going further with CDI
-
Upload
antonin-stefanutti -
Category
Technology
-
view
103 -
download
5
Transcript of Going further with CDI
![Page 1: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/1.jpg)
GoingfurtherwithCDI1.2
AntoineSabot-Durand·AntoninStefanutti
![Page 3: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/3.jpg)
CDI@Murex
CDIastheproductivityecosystemtobuildconnectivityinterfaces
![Page 4: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/4.jpg)
CDI@Murex
![Page 5: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/5.jpg)
AntoineSabot-Durand
SeniorSoftwareEngineerCDIco-speclead,JavaEE8EGRedHat,Inc.@antoine_sdwww.next-presso.comgithub.com/antoinesd
![Page 6: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/6.jpg)
ShouldIstayorshouldIgo?
AtalkaboutadvancedCDI
Mightbehardforbeginners
Don’tneedtobeaCDIguru
![Page 7: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/7.jpg)
@Inject @ProducesEvent<T> @Observes@Qualifier InjectionPoint
ShouldIstayorshouldIgo?
Ifyouknowthemostoftheseyoucanstay
![Page 8: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/8.jpg)
Moreconcretely
What’sincluded:
1. Realusecasesfromreallifewithrealusers2. Newapproachtointroduceportableextensionconcepts3. CodeinIDEwithtests
What’snotincluded:
1. IntroductiontoCDI2. Oldcontentonextension3. WorkwithContext(need2morehours)
![Page 9: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/9.jpg)
Toolsusedinthecode1/2
ApacheDeltaspike
1. ApacheDeltaSpikeisagreatCDItoolbox
2. Providehelperstodevelopextension3. Andacollectionofmoduleslike:
1. Security2. Data3. Scheduler
4. Moreinfoondeltaspike.apache.org
![Page 10: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/10.jpg)
Toolsusedinthecode2/2
Arquillian
1. Arquillianisanintegrationtestplatform2. ItintegrateswithJUnit3. Createyourdeploymentinadedicatedmethod
4. Andlaunchyourtestsagainstthecontainerofyourchoice
5. We’llusethe weld-se-embedded andweld-ee-embedded container
6. TherightsolutiontotestJavaEEcode7. Moreinfoonarquillian.org
![Page 11: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/11.jpg)
Agenda
MeetCDISPIIntroducingCDIExtensionsMetricsCDICDIQuizzCamelCDI
Slidesavailableatastefanutti.github.io/further-cdi
![Page 12: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/12.jpg)
MeetCDISPI
![Page 13: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/13.jpg)
SPIcanbesplitin4parts
![Page 14: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/14.jpg)
SPIcanbesplitin4parts
Typemeta-model
![Page 15: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/15.jpg)
SPIcanbesplitin4parts
CDImeta-model
![Page 16: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/16.jpg)
SPIcanbesplitin4parts
CDIentrypoints
![Page 17: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/17.jpg)
SPIcanbesplitin4parts
SPIdedicatedtoextensions
![Page 18: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/18.jpg)
Whyhavingatypemeta-model?
Because @Annotations areconfiguration
buttheyarealsoread-only
Sotoconfigureweneedamutablemeta-model…
… forannotatedtypes
![Page 19: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/19.jpg)
SPIfortypemeta-model
Annotated
TypegetBaseType()Set<Type>getTypeClosure()<TextendsAnnotation>getAnnotation(Class<T>)Set<Annotation>getAnnotations()booleanisAnnotationPresent(Class<?extendsAnnotation>)
AnnotatedMemberX
MembergetJavaMember()booleanisStatic()AnnotatedType<X>getDeclaringType()
AnnotatedParameterX
intgetPosition()AnnotatedCallable<X>getDeclaringCallable()
AnnotatedTypeX
Class<X>getJavaClass()Set<AnnotatedConstructor<X>>getConstructors()Set<AnnotatedMethod<?superX>>getMethods()Set<AnnotatedField<?superX>>getFields()
AnnotatedCallableX
List<AnnotatedParameter<X>>getParameters()
AnnotatedFieldX
FieldgetJavaMember()
AnnotatedConstructorX
Constructor<X>getJavaMember()
AnnotatedMethodX
MethodgetJavaMember()
![Page 20: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/20.jpg)
SPIdedicatedtoCDImeta-modelBeanAttributes
T
Set<Type>getTypes()Set<Annotation>getQualifiers()Class<?extendsAnnotation>getScope()StringgetName()Set<Class<?extendsAnnotation>>getStereotypes()booleanisAlternative()
BeanT
Class<?>getBeanClass()Set<InjectionPoint>getInjectionPoints()booleanisNullable()
InterceptorT
Set<Annotation>getInterceptorBindings()booleanintercepts(InterceptionTypetype)Objectintercept(InterceptionType,T,InvocationContext)
DecoratorT
TypegetDelegateType()Set<Annotation>getDelegateQualifiers()Set<Type>getDecoratedTypes()
ProducerT
Tproduce(CreationalContext<T>)voiddispose(T)Set<InjectionPoint>getInjectionPoints()
InjectionTargetT
voidinject(T,CreationalContext<T>)voidpostConstruct(T)voidpreDestroy(T)
InjectionPoint
TypegetType()Set<Annotation>getQualifiers()Bean<?>getBean()MembergetMember()AnnotatedgetAnnotated()booleanisDelegate()booleanisTransient()
ObserverMethodT
Class<?>getBeanClass()TypegetObservedType()Set<Annotation>getObservedQualifiers()ReceptiongetReception()TransactionPhasegetTransactionPhase()voidnotify(T)
EventMetadata
Set<Annotation>getQualifiers()InjectionPointgetInjectionPoint()TypegetType()
![Page 21: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/21.jpg)
ThisSPIcanbeusedinyourcode(1/2)
InjectionPoint canbeusedtogetinfoaboutwhat’sbeinginjected
@Qualifier@Retention(RetentionPolicy.RUNTIME)public@interfaceHttpParam{@NonbindingpublicStringvalue();}
@Produces@HttpParam("")StringgetParamValue(InjectionPointip,HttpServletRequestreq){returnreq.getParameter(ip.getAnnotated().getAnnotation(HttpParam.class).value());}
@Inject@HttpParam("productId")StringproductId;
![Page 22: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/22.jpg)
ThisSPIcanbeusedinyourcode(2/2)
InjectionPoint containsinfoaboutrequestedtypeat @Inject
classMyMapProducer(){
@Produces<K,V>Map<K,V>produceMap(InjectionPointip){if(valueIsNumber(((ParameterizedType)ip.getType())))returnnewTreeMap<K,V>();returnnewHashMap<K,V>();}
booleanvalueIsNumber(ParameterizedTypetype){Class<?>valueClass=(Class<?>)type.getActualTypeArguments()[1];returnNumber.class.isAssignableFrom(valueClass)}}
![Page 23: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/23.jpg)
SPIprovidingCDIentrypoints
UnmanagedT
Unmanaged(BeanManager,Class<T>)Unmanaged(Class<T>)UnmanagedInstance<T>newInstance()
UnmanagedInstanceT
Tget()UnmanagedInstance<T>produce()UnmanagedInstance<T>inject()UnmanagedInstance<T>postConstruct()UnmanagedInstance<T>preDestroy()UnmanagedInstance<T>dispose()
CDIProvider
CDI<Object>getCDI()
BeanManager
ObjectgetReference(Bean<?>,Type,CreationalContext<?>)ObjectgetInjectableReference(InjectionPoint,CreationalContext<?>)Set<Bean<?>>getBeans(Type,Annotation[])Bean<?extendsX>resolve(Set<Bean<?extendsX>>)voidvalidate(InjectionPoint)voidfireEvent(Object,Annotation[])
booleanisQualifier(Class<?extendsAnnotation>)booleanisStereotype(Class<?extendsAnnotation>)booleanareQualifiersEquivalent(Annotation,Annotation)booleanareInterceptorBindingsEquivalent(Annotation,Annotation)ContextgetContext(Class<?extendsAnnotation>)ELResolvergetELResolver()ExpressionFactorywrapExpressionFactory(ExpressionFactory)AnnotatedType<T>createAnnotatedType(Class<T>)InjectionTarget<T>createInjectionTarget(AnnotatedType<T>)InjectionTargetFactory<T>getInjectionTargetFactory(AnnotatedType<T>)BeanAttributes<T>createBeanAttributes(AnnotatedType<T>)Bean<T>createBean(BeanAttributes<T>,Class<X>,ProducerFactory<X>)InjectionPointcreateInjectionPoint(AnnotatedField<?>)
somemethodsskiped
CDIT
Set<CDIProvider>discoveredProvidersCDIProviderconfiguredProvider
CDI<Object>current()voidsetCDIProvider(CDIProviderprovider)BeanManagergetBeanManager()
![Page 24: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/24.jpg)
SPIdedicatedtoextensions
BeforeBeanDiscovery
addQualifier(Class<?extendsAnnotation>)addScope(Class<?extendsAnnotation>,boolean,boolean)addStereotype(Class<?extendsAnnotation>,Annotation[])addInterceptorBinding(Class<?extendsAnnotation>,Annotation[])addAnnotatedType(AnnotatedType<?>)
AfterTypeDiscovery
List<Class<?>>getAlternatives()List<Class<?>>getInterceptors()List<Class<?>>getDecorators()addAnnotatedType(AnnotatedType<?>,String)
AfterDeploymentValidation BeforeShutdown
AfterBeanDiscovery
addBean(Bean<?>)addObserverMethod(ObserverMethod<?>)addContext(Context)AnnotatedType<T>getAnnotatedType(Class<T>,String)Iterable<AnnotatedType<T>>getAnnotatedTypes(Class<T>)
ProcessAnnotatedTypeX
AnnotatedType<X>getAnnotatedType()voidsetAnnotatedType(AnnotatedType<X>)veto()
ProcessBeanX
AnnotatedgetAnnotated()Bean<X>getBean()
ProcessBeanAttributesT
AnnotatedgetAnnotated()BeanAttributes<T>getBeanAttributes()setBeanAttributes(BeanAttributes<T>)veto()
ProcessInjectionPointT,X
InjectionPointgetInjectionPoint()setInjectionPoint(InjectionPoint)
ProcessInjectionTargetX
AnnotatedType<X>getAnnotatedType()InjectionTarget<X>getInjectionTarget()setInjectionTarget(InjectionTarget<X>)
ProcessObserverMethodT,X
AnnotatedMethod<X>getAnnotatedMethod()ObserverMethod<T>getObserverMethod()
ProcessProducerT,X
AnnotatedMember<T>getAnnotatedMember()Producer<X>getProducer()setProducer(Producer<X>)
![Page 25: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/25.jpg)
AlltheseSPIinterfacesareeventscontainingmeta-modelSPI
TheseeventsfiredatboottimecanonlybeobservedinCDIextensions
Forinstance:
A ProcessAnnotatedType<T> eventisfiredforeachtypebeingdiscoveredatboottime
Observing ProcessAnnotatedType<Foo>allowsyoutoprevent Foo tobedeployedasabeanbycallingProcessAnnotatedType#veto()
![Page 26: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/26.jpg)
IntroducingCDIPortableExtensions
![Page 27: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/27.jpg)
Portableextensions
OneofthemostpowerfulfeatureoftheCDIspecification
Notreallypopularized,partlydueto:
1. Theirhighlevelofabstraction2. ThegoodknowledgeonBasicCDIandSPI3. Lackofinformation(CDIisoftenreducedtoabasicDIsolution)
![Page 28: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/28.jpg)
Extensions,whatfor?
Tointegrate3rdpartylibraries,frameworksorlegacycomponents
Tochangeexistingconfigurationorbehavior
ToextendCDIandJavaEE
Thankstothem,JavaEEcanevolvebetweenmajorreleases
![Page 29: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/29.jpg)
Extensions,how?
ObservingSPIeventsatboottimerelatedtothebeanmanagerlifecycle
Checkingwhatmeta-dataarebeingcreated
Modifyingthesemeta-dataorcreatingnewones
![Page 30: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/30.jpg)
Moreconcretely
Serviceprovideroftheservicejavax.enterprise.inject.spi.Extension declaredinMETA-INF/services
Justputthefullyqualifiednameofyourextensionclassinthisfile
importjavax.enterprise.event.Observes;importjavax.enterprise.inject.spi.Extension;
publicclassCdiExtensionimplementsExtension{
voidbeforeBeanDiscovery(@ObservesBeforeBeanDiscoverybbd){}//...
voidafterDeploymentValidation(@ObservesAfterDeploymentValidationadv){}}
![Page 31: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/31.jpg)
InternalStep HappenOnce LooponElements
Beanmanagerlifecycle
DeploymentStart
BeforeBean
Discovery
ScanArchive
ProcessAnnotated
Type
AfterType
Discovery
BeanEligibility
Check
ProcessInjectionPoint
ProcessInjectionTarget
ProcessBean
Attributes
ProcessBean
ProcessProducer
ProcessObserverMethod
AfterBean
Discovery
AfterDeploymentValidation
ApplicationRunning
BeforeShutdown
UndeployApplication
![Page 32: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/32.jpg)
Example:IgnoringJPAentities
ThefollowingextensionpreventsCDItomanageentities
Thisisacommonlyadmittedgoodpractice
publicclassVetoEntityimplementsExtension{
voidvetoEntity(@Observes@WithAnnotations(Entity.class)ProcessAnnotatedType<?>pat){pat.veto();}}
![Page 33: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/33.jpg)
ExtensionsarelaunchedduringbootstrapandarebasedonCDIevents
Oncetheapplicationisbootstrapped,theBeanManagerisinread-onlymode(noruntimebeanregistration)
Youonlyhaveto@Observes built-inCDIeventstocreateyourextensions
Remember
![Page 34: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/34.jpg)
Howtointegratea3rdpartyLibrary(DropwizardMetrics)intotheCDIProgrammingModel
3rdpartyLibrary
![Page 35: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/35.jpg)
AboutDropwizardMetrics
Providesdifferentmetrictypes: Counter , Gauge , Meter , Timer ,…
Providesdifferentreporter:JMX,console,SLF4J,CSV,servlet,…
Providesa MetricRegistry whichcollectsallyourappmetrics
ProvidesannotationsforAOPframeworks: @Counted , @Timed ,…
… butdoesnotincludeintegrationwiththeseframeworks
Moreatdropwizard.github.io/metrics
![Page 36: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/36.jpg)
DiscoverhowwecreatedCDIintegrationmoduleforMetrics
![Page 37: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/37.jpg)
Metricsoutofthebox(withoutCDI)classMetricsHelper{publicstaticMetricRegistryregistry=newMetricRegistry();}
classTimedMethodClass{
voidtimedMethod(){Timertimer=MetricsHelper.registry.timer("timer");Timer.Contexttime=timer.time();try{/*...*/}finally{time.stop();}}}
Notethatif Timer called "timer" doesn’texist, MetricRegistry willcreateadefaultoneandregisterit
1
1
![Page 38: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/38.jpg)
BasicCDIintegrationclassMetricRegistryBean{@Produces@ApplicationScopedMetricRegistryregistry=newMetricRegistry();}
classTimedMethodBean{@InjectMetricRegistryregistry;
voidtimedMethod(){Timertimer=registry.timer("timer");Timer.Contexttime=timer.time();try{/*...*/}finally{time.stop();}}}
WecouldhavealotmorewithadvancedCDIfeatures
![Page 39: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/39.jpg)
Ourgoals1. ApplyametricwiththeprovidedannotationinAOPstyle
@Timed("timer")voidtimedMethod(){//...}
2. Registerautomaticallyproducedcustommetrics@Produces@Metric(name="myTimer")Timertimer=newTimer(newSlidingTimeWindowReservoir(1L,TimeUnit.MINUTES));//...@Timed("myTimer")voidtimedMethod(){/*...*/}
AnnotationsprovidedbyMetrics
1
1
1
1
![Page 40: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/40.jpg)
StepstoapplyatimerinAOPstyle
Createaninterceptorforthetimertechnicalcode
MaketheMetricsannotation @Timed avalidinterceptorbindingannotation
Programmaticallyadd @Timed asaninterceptorbinding
Usethemagic
![Page 41: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/41.jpg)
Preparinginterceptorcreation
Tocreateaninterceptorweshouldstartbydetectingthe"technicalcode"thatwillwrapthe"businesscode"
classTimedMethodBean{
@InjectMetricRegistryregistry;
voidtimedMethod(){Timertimer=registry.timer("timer");Timer.Contexttime=timer.time();try{//Businesscode}finally{time.stop();}}}
![Page 42: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/42.jpg)
Creatingtheinterceptor
Interceptorisanindependentspecification(JSR318).Highlightedcodebelowispartofit.
@InterceptorclassTimedInterceptor{
@InjectMetricRegistryregistry;@AroundInvokeObjecttimeMethod(InvocationContextcontext)throwsException{Timertimer=registry.timer(context.getMethod().getAnnotation(Timed.class).name());Timer.Contexttime=timer.time();try{
returncontext.proceed();}finally{time.stop();}}}
InCDIaninterceptorisabean,youcaninjectotherbeansinit
Herethe"business"oftheapplicationiscalled.Allthecodearoundisthetechnicalone.
1
2
1
2
![Page 43: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/43.jpg)
Activatingtheinterceptor@Interceptor@Priority(Interceptor.Priority.LIBRARY_BEFORE)classTimedInterceptor{
@InjectMetricRegistryregistry;
@AroundInvokeObjecttimeMethod(InvocationContextcontext)throwsException{Timertimer=registry.timer(context.getMethod().getAnnotation(Timed.class).name());Timer.Contexttime=timer.time();try{returncontext.proceed();}finally{time.stop();}}}
Givinga @Priority toaninterceptoractivatesit.ThisannotationispartoftheCommonAnnotationsspecification(JSR250).InCDI,interceptoractivationcanalsobedoneinthe beans.xml file.
1
1
![Page 44: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/44.jpg)
Addabindingtotheinterceptor@Timed@Interceptor@Priority(Interceptor.Priority.LIBRARY_BEFORE)classTimedInterceptor{
@InjectMetricRegistryregistry;
@AroundInvokeObjecttimeMethod(InvocationContextcontext)throwsException{Timertimer=registry.timer(context.getMethod().getAnnotation(Timed.class).name());Timer.Contexttime=timer.time();try{returncontext.proceed();}finally{time.stop();}}}
We’lluseMetrics @Timed annotationasinterceptorbinding
1
1
![Page 45: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/45.jpg)
Backoninterceptorbinding
Aninterceptorbindingisanannotationusedin2kindofplaces:
1. Ontheinterceptordefinitionstoassociatethemtothisannotation2. Onthemethods/classestobeinterceptedbythisinterceptor
Aninterceptorbindingshouldbeannotatedwiththe@InterceptorBinding metaannotationorshouldbedeclaredasaninterceptorbindingprogrammatically
Iftheinterceptorbindingannotationhasmembers:
1. Theirvaluesaretakenintoaccounttodistinguishtwoinstances2. Unlessmembersareannotatedwith @NonBinding
![Page 46: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/46.jpg)
@Timed sourcecodetellsusit’snotaninterceptorbinding
@Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE,ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.ANNOTATION_TYPE})
public@interfaceTimed{
Stringname()default"";
booleanabsolute()defaultfalse;}
Lackof @InterceptorBinding annotationandwehavenocodetoadditprogrammatically
Noneofthemembershavethe @NonBinding annotationsothey’llbeusedtodistinguishtwoinstances(i.e.@Timed(name="timer1") and @Timed(name="timer2") willbe2differentinterceptorbindings)
1
2
2
1
2
![Page 47: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/47.jpg)
Theneeded @Timed sourcecodetomakeitaninterceptorbinding
@Documented@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE,ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.ANNOTATION_TYPE})@InterceptorBindingpublic@interfaceTimed{
@NonBindingStringname()default"";
@NonBindingbooleanabsolute()defaultfalse;}
Howtoobtaintherequired@Timed ?
Wecannottouchthecomponentsource/binary!
![Page 48: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/48.jpg)
Rememberthe AnnotatedType SPI?
ThankstoDeltaSpikewecaneasilycreatetherequired AnnotatedType
AnnotatedTypecreateTimedAnnotatedType()throwsException{AnnotationnonBinding=newAnnotationLiteral<Nonbinding>(){};returnnewAnnotatedTypeBuilder().readFromType(Timed.class).addToMethod(Timed.class.getMethod("name"),nonBinding).addToMethod(Timed.class.getMethod("absolute"),nonBinding).create();}
Thiscreatesaninstanceof @NonBinding annotation
Itwouldhavebeenpossiblebutfarmoreverbosetocreatethis AnnotatedType withoutthehelpofDeltaSpike.The AnnotatedTypeBuilder isinitializedfromtheMetrics @Timed annotation.
@NonBinding isaddedtobothmembersofthe @Timed annotation
123
3
1
2
3
![Page 49: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/49.jpg)
Add @Timed tothelistofinterceptorbindingwithanextension
Byobserving BeforeBeanDiscovery lifecycleevent
publicinterfaceBeforeBeanDiscovery{
addQualifier(Class<?extendsAnnotation>qualifier);addQualifier(AnnotatedType<?extendsAnnotation>qualifier);addScope(Class<?extendsAnnotation>scopeType,booleannormal,booleanpassivation);addStereotype(Class<?extendsAnnotation>stereotype,Annotation...stereotypeDef);addInterceptorBinding(AnnotatedType<?extendsAnnotation>bindingType);addInterceptorBinding(Class<?extendsAnnotation>bindingType,Annotation...bindingTypeDef);addAnnotatedType(AnnotatedType<?>type);addAnnotatedType(AnnotatedType<?>type,Stringid);}
Thismethodistheoneweneedtoaddourmodified @Timed AnnotatedType
1
1
![Page 50: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/50.jpg)
InternalStep HappenOnce LooponElements
BeforeBeanDiscovery isfirstinlifecycle
DeploymentStart
BeforeBean
Discovery
ScanArchive
ProcessAnnotated
Type
AfterType
Discovery
BeanEligibility
Check
ProcessInjectionPoint
ProcessInjectionTarget
ProcessBean
Attributes
ProcessBean
ProcessProducer
ProcessObserverMethod
AfterBean
Discovery
AfterDeploymentValidation
ApplicationRunning
BeforeShutdown
UndeployApplication
![Page 51: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/51.jpg)
ThisextensionwilldothejobclassMetricsExtensionimplementsExtension{
voidaddTimedBinding(@ObservesBeforeBeanDiscoverybbd)throwsException{bbd.addInterceptorBinding(createTimedAnnotatedType());}
privateAnnotatedTypecreateTimedAnnotatedType()throwsException{AnnotationnonBinding=newAnnotationLiteral<Nonbinding>(){};returnnewAnnotatedTypeBuilder().readFromType(Timed.class).addToMethod(Timed.class.getMethod("name"),nonBinding).addToMethod(Timed.class.getMethod("absolute"),nonBinding).create();}}
![Page 52: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/52.jpg)
Firstgoalachieved
Wecannowwrite:
@Timed("timer")voidtimedMethod(){//Businesscode}
AndhaveaMetricsTimer appliedtothemethod
![Page 53: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/53.jpg)
Secondgoal:Automaticallyregistercustommetrics
Whywouldwewantcustommetrics?
@AroundInvokeObjecttimedMethod(InvocationContextcontext)throwsException{Stringname=context.getMethod().getAnnotation(Timed.class).name();Timertimer=registry.timer(name);Timer.Contexttime=timer.time();try{returncontext.proceed();}finally{time.stop();}}
Theregistryprovidesadefault Timer (ifnonewasregisteredbytheuser).Thedefaulttimerhistogramisexponentiallybiasedtothepast5minutesofmeasurements.Wemaywanttohaveanotherbehavior.
1
1
![Page 54: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/54.jpg)
Automaticallyregistercustommetrics
Wewanttowritethis:
@Produces@Metric(name="myTimer")Timertimer=newTimer(newSlidingTimeWindowReservoir(1L,TimeUnit.MINUTES));
Andhave:
1. Thepossibilitytoretrievethis Timer fromtheregistrywhenit’sinjected(insteadofhavinganewinstancecreated)
2. This Timer producedwhenneeded(firstuse)3. This Timer registeredintheregistrywithitsname(here "myTimer" )
Thereare2 Metric :the com.codahale.metrics.Metric interfaceandthe com.codahale.metrics.annotation.Metric annotation
![Page 55: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/55.jpg)
Howtoachievethis?
Weneedtowriteanextensionthatwill:
1. Declare @Metric asaqualifiertoeaseinjectionandnameresolutionina BeforeBeanDiscovery observer
2. Changehowa Metric instancewillbeproducedtolookitupintheregistryandproduce(andregister)itonlyifit’snotfound.We’lldothisby:1. observingthe ProcessProducer lifecycleevent2. decoratingMetric Producer toaddthisnewbehavior
3. Produceall Metric instancesattheendofboottimetohavetheminregistryforruntime1. we’lldothisbyobserving AfterDeploymentValidation event
![Page 56: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/56.jpg)
InternalStep HappenOnce LooponElements
Sowewill @Observes these3eventstoaddourfeatures
DeploymentStart
BeforeBean
Discovery
ScanArchive
ProcessAnnotated
Type
AfterType
Discovery
BeanEligibility
Check
ProcessInjectionPoint
ProcessInjectionTarget
ProcessBean
Attributes
ProcessBean
ProcessProducer
ProcessObserverMethod
AfterBean
Discovery
AfterDeploymentValidation
ApplicationRunning
BeforeShutdown
UndeployApplication
![Page 57: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/57.jpg)
Adding @Metric tothelistofqualifiers
Thistimeweneedannotationmemberstobe"binding"( @Metric("a") and @Metric("b") shouldbedistinguished)
Sowedon’thavetoadd @Nonbinding annotationtothem
publicclassMetricExtensionimplementsExtension{
voidaddMetricQualifier(@ObservesBeforeBeanDiscoverybbd){bbd.addQualifier(Metric.class);}//...}
![Page 58: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/58.jpg)
Customizing Metric producingprocess
Wefirstneedtocreateourimplementationofthe Producer<X> SPI
classMetricProducer<XextendsMetric>implementsProducer<X>{
privatefinalProducer<X>delegate;
privatefinalBeanManagerbm;
privatefinalStringname;
MetricProducer(Producer<X>delegate,BeanManagerbm,Stringname){this.decorated=decorated;this.bm=bm;this.name=name;}//...
![Page 59: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/59.jpg)
Customizing Metric producingprocess(continued)//...@OverridepublicXproduce(CreationalContext<X>ctx){MetricRegistryregistry=BeanProvider.getContextualReference(bm,MetricRegistry.class,false);if(!registry.getMetrics().containsKey(name))registry.register(name,delegate.produce(ctx));return(X)registry.getMetrics().get(name);}
@Overridepublicvoiddispose(Xinstance){}
@OverridepublicSet<InjectionPoint>getInjectionPoints(){returndecorated.getInjectionPoints();}}
BeanProvider isaDeltaSpikehelperclasstoeasilyretrieveabeanorbeaninstance
Wedon’twanttohavetheproduced Metric instancedestroyedbytheCDIcontainer
1
2
1
2
![Page 60: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/60.jpg)
We’lluseour Producer<Metric> ina ProcessProducer observer
Throughthiseventwecansubstitutethestandardproducerbyours
publicinterfaceProcessProducer<T,X>{
AnnotatedMember<T>getAnnotatedMember();
Producer<X>getProducer();
voidsetProducer(Producer<X>producer);
voidaddDefinitionError(Throwablet);}
Getsthe AnnotatedMember associatedtothe @Produces fieldormethod
Getsthedefaultproducer(usefultodecorateit)
Overridestheproducer
1
2
3
1
2
3
![Page 61: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/61.jpg)
Customizing Metric producingprocess(end)
Here’stheextensioncodetodothisproducerdecoration
publicclassMetricExtensionimplementsExtension{//...<Xextendscom.codahale.metrics.Metric>voiddecorateMetricProducer(@ObservesProcessProducer<?,X>pp,BeanManagerbm){Stringname=pp.getAnnotatedMember().getAnnotation(Metric.class).name();pp.setProducer(newMetricProducer<>(pp.getProducer(),bm,name));}//...}
![Page 62: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/62.jpg)
Producingallthe Metric instancesattheendofboottime
Wedothatbyobservingthe AfterDeploymentValidation event
publicclassMetricExtensionimplementsExtension{//...voidregisterProduceMetrics(@ObservesAfterDeploymentValidationadv,BeanManagerbm){for(Bean<?>bean:bm.getBeans(com.codahale.metrics.Metric.class,newAnyLiteral()))for(Annotationqualifier:bean.getQualifiers())if(qualifierinstanceofMetric)BeanProvider.getContextualReference(bm,com.codahale.metrics.Metric.class,false,qualifier);}//...}
Getsallthe Metric beans
Retrievesaninstancethatwilluseourcustomproducerandthuswillfilltheregistry
1
2
1
2
![Page 63: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/63.jpg)
Secondgoalachieved
Wecannowwrite:
@Produces@Metric(name="myTimer")Timertimer=newTimer(newSlidingTimeWindowReservoir(1L,TimeUnit.MINUTES));
@InjectMetricRegistryregistry;
@Inject@Metric("myTimer")Metrictimer;
Andbesurethat registry.getMetrics().get("myTimer") andtimer arethesameobject(ourcustom Timer )
![Page 64: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/64.jpg)
CompleteextensioncodepublicclassMetricExtensionimplementsExtension{
voidaddMetricQualifier(@ObservesBeforeBeanDiscoverybbd){bbd.addQualifier(Metric.class);}
voidaddTimedInterceptorBinding(@ObservesBeforeBeanDiscoverybbd)throwsNoSuchMethodException{AnnotationnonBinding=newAnnotationLiteral<Nonbinding>(){};bbd.addInterceptorBinding(newAnnotatedTypeBuilder().readFromType(Timed.class).addToMethod(Timed.class.getMethod("name"),nonBinding).addToMethod(Timed.class.getMethod("absolute"),nonBinding).create());}
<Textendscom.codahale.metrics.Metric>voiddecorateMetricProducer(@ObservesProcessProducer<?,T>pp,BeanManagerbm){Stringname=pp.getAnnotatedMember().getAnnotation(Metric.class).name();pp.setProducer(newMetricProducer<>(pp.getProducer(),bm,name);}
voidregisterProduceMetrics(@ObservesAfterDeploymentValidationadv,BeanManagerbm){for(Bean<?>bean:bm.getBeans(com.codahale.metrics.Metric.class,newAnyLiteral()))for(Annotationqualifier:bean.getQualifiers())if(qualifierinstanceofMetric)BeanProvider.getContextualReference(bm,com.codahale.metrics.Metric.class,false,qualifier);}}
![Page 65: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/65.jpg)
TestyourCDIknowledge
Quizztime
![Page 66: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/66.jpg)
FindthevalidinjectionspointsclassMySuperBean{
@InjectBean<MySuperBean>myMeta;//A[]
@InjectBean<MyService>serviceMeta;//B[]
publicMySuperBean(@InjectMyServiceservice){/*...*/}//C[]
@InjectprivatevoidmyInitMethod(MyServiceservice){/*...*/}//D[]
@Inject@PostConstructpublicvoidmyInitMethod2(MyServiceservice){/*...*/}//E[]}
![Page 67: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/67.jpg)
SolutionclassMySuperBean{
@InjectBean<MySuperBean>myMeta;//A[X]
@InjectBean<MyService>serviceMeta;//B[]
publicMySuperBean(@InjectMyServiceservice){/*...*/}//C[]
@InjectprivatevoidmyInitMethod(MyServiceservice){/*...*/}//D[X]
@Inject@PostConstructpublicvoidmyInitMethod2(MyServiceservice){/*...*/}//E[]}
![Page 68: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/68.jpg)
FindBeanscandidateswithout beans.xml injar(CDI1.2)
@DecoratorpublicabstractclassMyDecoratorimplementsMyService{/*...*/}//A[]
@StatelesspublicclassMyServiceImplimplementsMyService{/*...*/}//B[]
publicclassMyBean{/*...*/}//C[]
@ModelpublicclassMyBean{/*...*/}//D[]
@SingletonpublicclassMyBean{/*...*/}//E[]
@ConversationScopedpublicclassMyBean{/*...*/}//F[]
![Page 69: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/69.jpg)
Solution@DecoratorpublicabstractclassMyDecoratorimplementsMyService{/*...*/}//A[X]
@StatelesspublicclassMyServiceImplimplementsMyService{/*...*/}//B[X]
publicclassMyBean{/*...*/}//C[]
@ModelpublicclassMyBean{/*...*/}//D[X]
@SingletonpublicclassMyBean{/*...*/}//E[]
@ConversationScopedpublicclassMyBean{/*...*/}//F[X]
![Page 70: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/70.jpg)
Findthevalidproducers@ApplicationScopedpublicclassMyBean{
@ProducespublicServiceproduce1(InjectionPointip,Bean<Service>myMeta){/*...*/}//A[]
@Produces@SessionScopedpublicServiceproduce2(InjectionPointip){/*...*/}//B[]
@ProducespublicMap<K,V>produceMap(InjectionPointip){/*...*/}//C[]
@ProducespublicMap<String,?extendsService>produceMap2(){/*...*/}//D[]}
![Page 71: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/71.jpg)
Solution@ApplicationScopedpublicclassMyBean{
@ProducespublicServiceproduce1(InjectionPointip,Bean<Service>myMeta){/*...*/}//A[X]
@Produces@SessionScopedpublicServiceproduce2(InjectionPointip){/*...*/}//B[]
@ProducespublicMap<K,V>produceMap(InjectionPointip){/*...*/}//C[X]
@ProducespublicMap<String,?extendsService>produceMap2(){/*...*/}//D[]}
![Page 72: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/72.jpg)
Whichobserverswillbetriggered?classFirstBean{
@InjectEvent<Post>postEvent;
publicvoidsaveNewPost(PostmyPost){postEvent.select(newAnnotationLiteral()<French>{}).fire(myPost);}}
classSecondBean{
voidlistenFrPost(@Observes@FrenchPostpost){/*...*/}//A[]voidlistenPost(@ObservesPostpost){/*...*/}//B[]voidlistenEnPost(@Observes@EnglishPostpost){/*...*/}//C[]voidlistenObject(@ObservesObjectobj){/*...*/}//D[]}
![Page 73: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/73.jpg)
SolutionclassFirstBean{
@InjectEvent<Post>postEvent;
publicvoidsaveNewPost(PostmyPost){postEvent.select(newAnnotationLiteral()<French>{}).fire(myPost);}}
classSecondBean{
voidlistenFrPost(@Observes@FrenchPostpost){/*...*/}//A[X]voidlistenPost(@ObservesPostpost){/*...*/}//B[X]voidlistenEnPost(@Observes@EnglishPostpost){/*...*/}//C[]voidlistenObject(@ObservesObjectobj){/*...*/}//D[X]}
![Page 74: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/74.jpg)
HowtouseCDIasdependencyinjectioncontainerforanintegrationframework(ApacheCamel)
CamelCDI
![Page 75: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/75.jpg)
AboutApacheCamel
Open-sourceintegrationframeworkbasedonknownEnterpriseIntegrationPatterns
ProvidesavarietyofDSLstowriteroutingandmediationrules
ProvidessupportforbeanbindingandseamlessintegrationwithDIframeworks
![Page 76: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/76.jpg)
DiscoverhowwecreatedCDIintegrationmoduleforCamel
![Page 77: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/77.jpg)
Cameloutofthebox(withoutCDI)publicstaticvoidmain(String[]args){CamelContextcontext=newDefaultCamelContext();context.addRoutes(newRouteBuilder(){publicvoidconfigure(){from("file:target/input?delay=1000").convertBodyTo(String.class).log("Sendingmessage[${body}]toJMS...").to("sjms:queue:output");}});PropertiesComponentproperties=newPropertiesComponent();properties.setLocation("classpath:camel.properties");context.addComponent("properties",properties);//Registersthe"properties"component
SjmsComponentcomponent=newSjmsComponent();component.setConnectionFactory(newActiveMQConnectionFactory("vm://broker?broker.persistent=false"));jms.setConnectionCount(Integer.valueOf(context.resolvePropertyPlaceholders("{{jms.maxConnections}}")));context.addComponent("sjms",jms);//Registersthe"sjms"component
context.start();}
ThisroutewatchesadirectoryeverysecondandsendsnewfilescontenttoaJMSqueue
1
1
![Page 78: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/78.jpg)
BasicCDIintegration(1/3)1. CamelcomponentsandroutebuilderasCDIbeans2. BindtheCamelcontextlifecycletothatoftheCDIcontainer
classFileToJmsRouteBeanextendsRouteBuilder{
@Overridepublicvoidconfigure(){from("file:target/input?delay=1000").convertBodyTo(String.class).log("Sendingmessage[${body}]toJMS...").to("sjms:queue:output");}}
![Page 79: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/79.jpg)
BasicCDIintegration(2/3)classPropertiesComponentFactoryBean{
@Produces@ApplicationScopedPropertiesComponentpropertiesComponent(){PropertiesComponentproperties=newPropertiesComponent();properties.setLocation("classpath:camel.properties");returnproperties;}}
classJmsComponentFactoryBean{
@Produces@ApplicationScopedSjmsComponentsjmsComponent(PropertiesComponentproperties)throwsException{SjmsComponentjms=newSjmsComponent();jms.setConnectionFactory(newActiveMQConnectionFactory("vm://broker?broker.persistent=false"));jms.setConnectionCount(Integer.valueOf(properties.parseUri("{{jms.maxConnections}}")));returncomponent;}}
![Page 80: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/80.jpg)
BasicCDIintegration(3/3)@ApplicationScopedclassCamelContextBeanextendsDefaultCamelContext{
@InjectCamelContextBean(FileToJmsRouteBeanroute,SjmsComponentjms,PropertiesComponentproperties){addComponent("properties",properties);addComponent("sjms",jms);addRoutes(route);}@PostConstructvoidstartContext(){super.start();}@PreDestroyvoidpreDestroy(){super.stop();}}
WecouldhavealotmorewithadvancedCDIfeatures
![Page 81: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/81.jpg)
Ourgoals1. Avoidassemblingandconfiguringthe CamelContext manually2. AccessCDIbeansfromtheCamelDSLautomatically
.to("sjms:queue:output");//Lookupbyname(sjms)andtype(Component)
context.resolvePropertyPlaceholders("{{jms.maxConnections}}");//Lookupbyname(properties)andtype(Component)
3. SupportCamelannotationsinCDIbeans@PropertyInject(value="jms.maxConnections",defaultValue="10")intmaxConnections;
![Page 82: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/82.jpg)
StepstointegrateCamelandCDI
Managethecreationandtheconfigurationofthe CamelContextbean
Bindthe CamelContext lifecyclethatoftheCDIcontainer
ImplementtheCamelSPItolookupCDIbeanreferences
Useacustom InjectionTarget forCDIbeanscontainingCamelannotations
Usethemagic
![Page 83: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/83.jpg)
Howtoachievethis?
Weneedtowriteanextensionthatwill:
1. Declarea CamelContext beanbyobservingthe AfterBeanDiscoverylifecycleevent
2. Instantiatethebeansoftype RouteBuilder andaddthemtotheCamelcontext
3. Start(resp.stop)theCamelcontextwhentheAfterDeploymentValidation eventisfired(resp.the BeforeShutdownevent)
4. CustomizetheCamelcontexttoquerythe BeanManager tolookupCDIbeansbynameandtype
5. DetectCDIbeanscontainingCamelannotationsbyobservingtheProcessAnnotatedType eventandmodifyhowtheygetinjectedbyobservingthe ProcessInjectionTarget lifecycleevent
![Page 84: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/84.jpg)
InternalStep HappenOnce LooponElements
Sowewill @Observes these5eventstoaddourfeatures
DeploymentStart
BeforeBean
Discovery
ScanArchive
ProcessAnnotated
Type
AfterType
Discovery
BeanEligibility
Check
ProcessInjectionPoint
ProcessInjectionTarget
ProcessBean
Attributes
ProcessBean
ProcessProducer
ProcessObserverMethod
AfterBean
Discovery
AfterDeploymentValidation
ApplicationRunning
BeforeShutdown
UndeployApplication
![Page 85: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/85.jpg)
Addingthe CamelContext bean
Automaticallyadda CamelContext beaninthedeploymentarchive
Howtoaddabeanprogrammatically?
![Page 86: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/86.jpg)
Declaringabeanprogrammatically
Weneedtoimplementthe Bean SPI
publicinterfaceBean<T>extendsContextual<T>,BeanAttributes<T>{
Class<?>getBeanClass();Set<InjectionPoint>getInjectionPoints();Tcreate(CreationalContext<T>creationalContext);//Contextual<T>voiddestroy(Tinstance,CreationalContext<T>creationalContext);Set<Type>getTypes();//BeanAttributes<T>Set<Annotation>getQualifiers();Class<?extendsAnnotation>getScope();StringgetName();Set<Class<?extendsAnnotation>>getStereotypes();booleanisAlternative();}
![Page 87: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/87.jpg)
Implementingthe Bean SPIclassCamelContextBeanimplementsBean<CamelContext>{
publicClass<?extendsAnnotation>getScope(){returnApplicationScoped.class;}
publicSet<Annotation>getQualifiers(){returnCollections.singleton((Annotation)newAnnotationLiteral<Default>(){});}publicSet<Type>getTypes(){returnCollections.singleton((Type)CamelContext.class);}
publicCamelContextcreate(CreationalContext<CamelContext>creational){returnnewDefaultCamelContext();}publicvoiddestroy(CamelContextinstance,CreationalContext<CamelContext>creational){}
publicClass<?>getBeanClass(){returnDefaultCamelContext.class;}
publicSet<InjectionPoint>getInjectionPoints(){returnCollections.emptySet();}
publicSet<Class<?extendsAnnotation>>getStereotypes(){returnCollections.emptySet();}publicStringgetName(){return"camel-cdi";}publicbooleanisAlternative(){returnfalse;}publicbooleanisNullable(){returnfalse;}}
![Page 88: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/88.jpg)
Addingaprogrammaticbeantothedeployment
Thenaddthe CamelContextBean beanprogrammaticallybyobservingthe AfterBeanDiscovery lifecyleevent
publicclassCamelExtensionimplementsExtension{
voidaddCamelContextBean(@ObservesAfterBeanDiscoveryabd){abd.addBean(newCamelContextBean());}}
![Page 89: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/89.jpg)
InstantiateandassembletheCamelcontext
Instantiatethe CamelContext beanandthe RouteBuilder beansintheAfterDeploymentValidation lifecycleevent
publicclassCamelExtensionimplementsExtension{//...voidconfigureContext(@ObservesAfterDeploymentValidationadv,BeanManagerbm){CamelContextcontext=getReference(bm,CamelContext.class);for(Bean<?>bean:bm.getBeans(RoutesBuilder.class))context.addRoutes(getReference(bm,RouteBuilder.class,bean));}<T>TgetReference(BeanManagerbm,Class<T>type){returngetReference(bm,type,bm.resolve(bm.getBeans(type)));}<T>TgetReference(BeanManagerbm,Class<T>type,Bean<?>bean){return(T)bm.getReference(bean,type,bm.createCreationalContext(bean));}}
![Page 90: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/90.jpg)
ManagedtheCamelcontextlifecycle
Start(resp.stop)theCamelcontextwhentheAfterDeploymentValidation eventisfired(resp.the BeforeShutdown )
publicclassCamelExtensionimplementsExtension{//...voidconfigureContext(@ObservesAfterDeploymentValidationadv,BeanManagerbm){CamelContextcontext=getReference(bm,CamelContext.class);for(Bean<?>bean:bm.getBeans(RoutesBuilder.class)context.addRoutes(getReference(bm,RouteBuilder.class,bean);context.start();}voidstopCamelContext(@ObservesBeforeShutdownbs,BeanManagerbm){CamelContextcontext=getReference(bm,CamelContext.class);context.stop();}}
![Page 91: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/91.jpg)
Firstgoalachieved
Wecangetridofthefollowingcode:
@ApplicationScopedclassCamelContextBeanextendsDefaultCamelContext{@InjectCamelContextBean(FileToJmsRouteBeanroute,SjmsComponentjms,PropertiesComponentproperties){addComponent("properties",propertiesComponent);addComponent("sjms",sjmsComponent);addRoutes(route);}@PostConstructvoidstartContext(){super.start();}@PreDestroyvoidstopContext(){super.stop();}}
![Page 92: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/92.jpg)
Secondgoal:AccessCDIbeansfromtheCamelDSL
HowtoretrieveCDIbeansfromtheCamelDSL?
.to("sjms:queue:output");//Lookupbyname(sjms)andtype(Component)context.resolvePropertyPlaceholders("{{jms.maxConnections}}");//Lookupbyname(properties)andtype(Component)
//Andalso....bean(MyBean.class);//LookupbytypeandDefaultqualifier.beanRef("beanName");//Lookupbyname
ImplementtheCamelregistrySPIandusethe BeanManager tolookupforCDIbeancontextualreferencesbynameandtype
![Page 93: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/93.jpg)
ImplementtheCamelregistrySPIclassCamelCdiRegistryimplementsRegistry{privatefinalBeanManagerbm;
CamelCdiRegistry(BeanManagerbm){this.bm=bm;}
public<T>TlookupByNameAndType(Stringname,Class<T>type){returngetReference(bm,type,bm.resolve(bm.getBeans(name)));}public<T>Set<T>findByType(Class<T>type){returngetReference(bm,type,bm.resolve(bm.getBeans(type)));}publicObjectlookupByName(Stringname){returnlookupByNameAndType(name,Object.class);}<T>TgetReference(BeanManagerbm,Typetype,Bean<?>bean){return(T)bm.getReference(bean,type,bm.createCreationalContext(bean));}}
![Page 94: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/94.jpg)
Addthe CamelCdiRegistry totheCamelcontext
classCamelContextBeanimplementsBean<CamelContext>{privatefinalBeanManagerbm;
CamelContextBean(BeanManagerbm){this.bm=bm;}//...publicCamelContextcreate(CreationalContext<CamelContext>creational){returnnewDefaultCamelContext(newCamelCdiRegistry(bm));}}
publicclassCamelExtensionimplementsExtension{//...voidaddCamelContextBean(@ObservesAfterBeanDiscoveryabd,BeanManagerbm){abd.addBean(newCamelContextBean(bm));}}
![Page 95: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/95.jpg)
Secondgoalachieved1/3
Wecandeclarethe sjms componentwiththe @Named qualifier
classJmsComponentFactoryBean{
@Produces@Named("sjms")@ApplicationScopedSjmsComponentsjmsComponent(PropertiesComponentproperties){SjmsComponentjms=newSjmsComponent();jms.setConnectionFactory(newActiveMQConnectionFactory("vm://broker?..."));jms.setConnectionCount(Integer.valueOf(properties.parseUri("{{jms.maxConnections}}")));returncomponent;}}
…
![Page 96: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/96.jpg)
Secondgoalachieved2/3
Declarethe properties componentwiththe @Named qualifier
classPropertiesComponentFactoryBean{
@Produces@Named("properties")@ApplicationScopedPropertiesComponentpropertiesComponent(){PropertiesComponentproperties=newPropertiesComponent();properties.setLocation("classpath:camel.properties");returnproperties;}}
…
![Page 97: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/97.jpg)
Secondgoalachieved3/3
Andgetridofthecoderelatedtothe properties and sjmscomponentsregistration
@ApplicationScopedclassCamelContextBeanextendsDefaultCamelContext{@InjectCamelContextBean(FileToJmsRouteBeanroute,SjmsComponentjms,PropertiesComponentproperties){addComponent("properties",propertiesComponent);addComponent("sjms",sjmsComponent);addRoutes(route);}@PostConstructvoidstartContext(){super.start();}@PreDestroyvoidstopContext(){super.stop();}}
![Page 98: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/98.jpg)
Thirdgoal:SupportCamelannotationsinCDIbeans
CamelprovidesasetofDIframeworkagnosticannotationsforresourceinjection
@PropertyInject(value="jms.maxConnections",defaultValue="10")intmaxConnections;
//Butalso...@EndpointInject(uri="jms:queue:foo")Endpointendpoint;
@BeanInject("foo")FooBeanfoo;
Howtosupportcustomannotationsinjection?
![Page 99: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/99.jpg)
Howtosupportcustomannotationsinjection?
Createacustom InjectionTarget thatusesthedefaultCamelbeanpostprocessor DefaultCamelBeanPostProcessor
publicinterfaceInjectionTarget<T>extendsProducer<T>{voidinject(Tinstance,CreationalContext<T>ctx);voidpostConstruct(Tinstance);voidpreDestroy(Tinstance);}
HookitintotheCDIinjectionmechanismbyobservingtheProcessInjectionTarget lifecycleevent
OnlyforbeanscontainingCamelannotationsbyobservingtheProcessAnnotatedType lifecycleandusing @WithAnnotations
![Page 100: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/100.jpg)
Createacustom InjectionTargetclassCamelInjectionTarget<T>implementsInjectionTarget<T>{
finalInjectionTarget<T>delegate;
finalDefaultCamelBeanPostProcessorprocessor;
CamelInjectionTarget(InjectionTarget<T>target,finalBeanManagerbm){delegate=target;processor=newDefaultCamelBeanPostProcessor(){publicCamelContextgetOrLookupCamelContext(){returngetReference(bm,CamelContext.class);}};}publicvoidinject(Tinstance,CreationalContext<T>ctx){processor.postProcessBeforeInitialization(instance,null);delegate.inject(instance,ctx);}//...}
CalltheCameldefaultbeanpost-processorbeforeCDIinjection
1
1
![Page 101: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/101.jpg)
Registerthecustom InjectionTarget
Observethe ProcessInjectionTarget lifecyleeventandsettheInjectionTarget
publicinterfaceProcessInjectionTarget<X>{AnnotatedType<X>getAnnotatedType();InjectionTarget<X>getInjectionTarget();voidsetInjectionTarget(InjectionTarget<X>injectionTarget);voidaddDefinitionError(Throwablet);}
Todecorateitwiththe CamelInjectionTarget
classCamelExtensionimplementsExtension{
<T>voidcamelBeansPostProcessor(@ObservesProcessInjectionTarget<T>pit,BeanManagerbm){pit.setInjectionTarget(newCamelInjectionTarget<>(pit.getInjectionTarget(),bm));}}
![Page 102: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/102.jpg)
ButonlyforbeanscontainingCamelannotationsclassCamelExtensionimplementsExtension{finalSet<AnnotatedType<?>>camelBeans=newHashSet<>();
voidcamelAnnotatedTypes(@Observes@WithAnnotations(PropertyInject.class)ProcessAnnotatedType<?>pat){camelBeans.add(pat.getAnnotatedType());}
<T>voidcamelBeansPostProcessor(@ObservesProcessInjectionTarget<T>pit,BeanManagerbm){if(camelBeans.contains(pit.getAnnotatedType()))pit.setInjectionTarget(newCamelInjectionTarget<>(pit.getInjectionTarget(),bm));}}
DetectallthetypescontainingCamelannotationswith @WithAnnotations
Decoratethe InjectionTarget correspondingtothesetypes
1
2
1
2
![Page 103: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/103.jpg)
Thirdgoalachieved1/2
Insteadofinjectingthe PropertiesComponent beantoresolveaconfigurationproperty
classJmsComponentFactoryBean{
@Produces@Named("sjms")@ApplicationScopedSjmsComponentsjmsComponent(PropertiesComponentproperties){SjmsComponentjms=newSjmsComponent();jms.setConnectionFactory(newActiveMQConnectionFactory("vm://broker?..."));jms.setConnectionCount(Integer.valueOf(properties.parseUri("{{jms.maxConnections}}")));returncomponent;}}
![Page 104: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/104.jpg)
Thirdgoalachieved2/2
Wecandirectlyrelyonthe @PropertyInject CamelannotationinCDIbeans
classJmsComponentFactoryBean{
@PropertyInject(value="jms.maxConnections",defaultValue="10")intmaxConnections;
@Produces@Named("sjms")@ApplicationScopedSjmsComponentsjmsComponent(){SjmsComponentcomponent=newSjmsComponent();jms.setConnectionFactory(newActiveMQConnectionFactory("vm://broker?..."));component.setConnectionCount(maxConnections);returncomponent;}}
![Page 105: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/105.jpg)
Bonusgoal:CamelDSLAOP
AOPinstrumentationoftheCamelDSL
from("file:target/input?delay=1000").convertBodyTo(String.class).log("Sendingmessage[${body}]toJMS...").to("sjms:queue:output");
withCDIobservers
from("file:target/input?delay=1000").convertBodyTo(String.class).to("sjms:queue:output").id("joinpoint");}voidadvice(@Observes@NodeId("joinpoint")Exchangeexchange){logger.info("Sendingmessage[{}]toJMS...",exchange.getIn().getBody());}
![Page 106: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/106.jpg)
Howtoachievethis?
WecancreateaCDIqualifiertoholdtheCamelnodeidmetadata:
@Qualifier@Retention(RetentionPolicy.RUNTIME)public@interfaceNodeId{Stringvalue();}
andcreateanextensionthatwill:
1. DetecttheCDIbeanscontainingobservermethodswiththe @NodeIdqualifierbyobservingthe ProcessObserverMethod eventandcollecttheCamelprocessornodestobeinstrumented
2. CustomizetheCamelcontextbyprovidinganimplementationoftheCamel InterceptStrategy interfacethatwillfireaCDIeventeachtimean Exchange isprocessedbytheinstrumentednodes
![Page 107: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/107.jpg)
DetecttheCamelDSLAOPobservermethods
Observethe ProcessObserverMethod lifecyleevent
publicinterfaceProcessObserverMethod<T,X>{AnnotatedMethod<X>getAnnotatedMethod();ObserverMethod<T>getObserverMethod();voidaddDefinitionError(Throwablet);}
Andcollecttheobservermethodmetadata
classCamelExtensionimplementsExtension{finalSet<NodeId>joinPoints=newHashSet<>();
voidpointcuts(@ObservesProcessObserverMethod<Exchange,?>pom){for(Annotationqualifier:pom.getObserverMethod().getObservedQualifiers())if(qualifierinstanceofNodeId)joinPoints.add(NodeId.class.cast(qualifier));}}
![Page 108: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/108.jpg)
InstrumenttheCamelcontext
InterceptmatchingnodesandfireaCDIevent
voidconfigureCamelContext(@ObservesAfterDeploymentValidationadv,finalBeanManagermanager){context.addInterceptStrategy(newInterceptStrategy(){publicProcessorwrapProcessorInInterceptors(CamelContextcontext,ProcessorDefinition<?>definition,Processortarget,ProcessornextTarget)throwsException{if(definition.hasCustomIdAssigned()){for(finalNodenode:joinPoints){if(node.value().equals(definition.getId())){returnnewDelegateAsyncProcessor(target){publicbooleanprocess(Exchangeexchange,AsyncCallbackcallback){manager.fireEvent(exchange,node);returnsuper.process(exchange,callback);}};}}}returntarget;}});}
![Page 109: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/109.jpg)
Bonusgoalachieved
WecandefinejoinpointsintheCamelDSL
from("file:target/input?delay=1000").convertBodyTo(String.class).to("sjms:queue:output").id("joinpoint");}
AndadvisethemwithCDIobservers
voidadvice(@Observes@NodeId("joinpoint")Exchangeexchange){List<MessageHistory>history=exchange.getProperty(Exchange.MESSAGE_HISTORY,List.class);logger.info("Sendingmessage[{}]to[{}]...",exchange.getIn().getBody(),history.get(history.size()-1).getNode().getLabel());}
![Page 110: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/110.jpg)
Conclusion
![Page 111: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/111.jpg)
References
CDISpecification-cdi-spec.org
MetricsCDIsources-github.com/astefanutti/metrics-cdi
CamelCDIsources-github.com/astefanutti/camel-cdi
Slidessources-github.com/astefanutti/further-cdi
SlidesgeneratedwithAsciidoctor,PlantUMLandDZSlidesbackend
Originalslidetemplate-DanAllen&SarahWhite
![Page 112: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/112.jpg)
AntoineSabot-DurandAntoninStefanutti@antoine_sd@astefanut
![Page 113: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/113.jpg)
Annexes
![Page 114: Going further with CDI](https://reader034.fdocuments.in/reader034/viewer/2022042817/55a78a1c1a28ab5a5e8b45f1/html5/thumbnails/114.jpg)
CompletelifecycleeventsApplication lifecycle
BeforeBeanDiscovery
AfterTypeDiscovery
AfterBeanDiscovery
AfterDeploymentValidation
Type Discovery
ProcessAnnotatedType<X>
yes
whiletypesindeploymentarchive?
no
Bean Discovery
For each discovered types during type discovery
ProcessInjectionPoint<T,X>
ProcessInjectionTarget<X>
ProcessBeanAttributes<T>
ProcessManagedBean<X>
For each producer methods / fields of enabled beans
ProcessInjectionPoint<T,X>
ProcessProducer<T,X>
ProcessBeanAttributes<T>
ProcessProducerMethod<T,X>ProcessProducerField<T,X>
For each observer methods of enabled beans
ProcessInjectionPoint<T,X>
ProcessObserverMethod<T,X>