@@ -109,19 +109,34 @@ private static final class FeatureRegistration {
109109 private final Class <? extends Feature > featureClass ;
110110 private final Feature feature ;
111111 private final RuntimeType runtimeType ;
112+ private final int priority ;
112113
113- private FeatureRegistration (final Class <? extends Feature > featureClass ) {
114+ private FeatureRegistration (final Class <? extends Feature > featureClass , int priority ) {
114115 this .featureClass = featureClass ;
115116 this .feature = null ;
116117 final ConstrainedTo runtimeTypeConstraint = featureClass .getAnnotation (ConstrainedTo .class );
117118 this .runtimeType = runtimeTypeConstraint == null ? null : runtimeTypeConstraint .value ();
119+ this .priority = priority (featureClass , priority );
118120 }
119121
120- private FeatureRegistration (final Feature feature ) {
122+ private FeatureRegistration (final Feature feature , int priority ) {
121123 this .featureClass = feature .getClass ();
122124 this .feature = feature ;
123125 final ConstrainedTo runtimeTypeConstraint = featureClass .getAnnotation (ConstrainedTo .class );
124126 this .runtimeType = runtimeTypeConstraint == null ? null : runtimeTypeConstraint .value ();
127+ this .priority = priority (featureClass , priority );
128+ }
129+
130+ private static int priority (Class <? extends Feature > featureClass , int priority ) {
131+ if (priority != ContractProvider .NO_PRIORITY ) {
132+ return priority ;
133+ }
134+ final Priority priorityAnnotation = featureClass .getAnnotation (Priority .class );
135+ if (priorityAnnotation != null ) {
136+ return priorityAnnotation .value ();
137+ } else {
138+ return Priorities .USER ;
139+ }
125140 }
126141
127142 /**
@@ -400,7 +415,7 @@ public CommonConfig property(final String name, final Object value) {
400415 public CommonConfig register (final Class <?> componentClass ) {
401416 checkComponentClassNotNull (componentClass );
402417 if (componentBag .register (componentClass , getModelEnhancer (componentClass ))) {
403- processFeatureRegistration (null , componentClass );
418+ processFeatureRegistration (null , componentClass , ContractProvider . NO_PRIORITY );
404419 }
405420
406421 return this ;
@@ -410,7 +425,7 @@ public CommonConfig register(final Class<?> componentClass) {
410425 public CommonConfig register (final Class <?> componentClass , final int bindingPriority ) {
411426 checkComponentClassNotNull (componentClass );
412427 if (componentBag .register (componentClass , bindingPriority , getModelEnhancer (componentClass ))) {
413- processFeatureRegistration (null , componentClass );
428+ processFeatureRegistration (null , componentClass , bindingPriority );
414429 }
415430
416431 return this ;
@@ -424,7 +439,7 @@ public CommonConfig register(final Class<?> componentClass, final Class<?>... co
424439 return this ;
425440 }
426441 if (componentBag .register (componentClass , asNewIdentitySet (contracts ), getModelEnhancer (componentClass ))) {
427- processFeatureRegistration (null , componentClass );
442+ processFeatureRegistration (null , componentClass , ContractProvider . NO_PRIORITY );
428443 }
429444
430445 return this ;
@@ -434,7 +449,7 @@ public CommonConfig register(final Class<?> componentClass, final Class<?>... co
434449 public CommonConfig register (final Class <?> componentClass , final Map <Class <?>, Integer > contracts ) {
435450 checkComponentClassNotNull (componentClass );
436451 if (componentBag .register (componentClass , contracts , getModelEnhancer (componentClass ))) {
437- processFeatureRegistration (null , componentClass );
452+ processFeatureRegistration (null , componentClass , ContractProvider . NO_PRIORITY );
438453 }
439454
440455 return this ;
@@ -446,7 +461,7 @@ public CommonConfig register(final Object component) {
446461
447462 final Class <?> componentClass = component .getClass ();
448463 if (componentBag .register (component , getModelEnhancer (componentClass ))) {
449- processFeatureRegistration (component , componentClass );
464+ processFeatureRegistration (component , componentClass , ContractProvider . NO_PRIORITY );
450465 }
451466
452467 return this ;
@@ -457,7 +472,7 @@ public CommonConfig register(final Object component, final int bindingPriority)
457472 checkProviderNotNull (component );
458473 final Class <?> componentClass = component .getClass ();
459474 if (componentBag .register (component , bindingPriority , getModelEnhancer (componentClass ))) {
460- processFeatureRegistration (component , componentClass );
475+ processFeatureRegistration (component , componentClass , bindingPriority );
461476 }
462477
463478 return this ;
@@ -472,7 +487,7 @@ public CommonConfig register(final Object component, final Class<?>... contracts
472487 return this ;
473488 }
474489 if (componentBag .register (component , asNewIdentitySet (contracts ), getModelEnhancer (componentClass ))) {
475- processFeatureRegistration (component , componentClass );
490+ processFeatureRegistration (component , componentClass , ContractProvider . NO_PRIORITY );
476491 }
477492
478493 return this ;
@@ -483,19 +498,19 @@ public CommonConfig register(final Object component, final Map<Class<?>, Integer
483498 checkProviderNotNull (component );
484499 final Class <?> componentClass = component .getClass ();
485500 if (componentBag .register (component , contracts , getModelEnhancer (componentClass ))) {
486- processFeatureRegistration (component , componentClass );
501+ processFeatureRegistration (component , componentClass , ContractProvider . NO_PRIORITY );
487502 }
488503
489504 return this ;
490505 }
491506
492- private void processFeatureRegistration (final Object component , final Class <?> componentClass ) {
507+ private void processFeatureRegistration (final Object component , final Class <?> componentClass , int priority ) {
493508 final ContractProvider model = componentBag .getModel (componentClass );
494509 if (model .getContracts ().contains (Feature .class )) {
495510 @ SuppressWarnings ("unchecked" )
496511 final FeatureRegistration registration = (component != null )
497- ? new FeatureRegistration ((Feature ) component )
498- : new FeatureRegistration ((Class <? extends Feature >) componentClass );
512+ ? new FeatureRegistration ((Feature ) component , priority )
513+ : new FeatureRegistration ((Class <? extends Feature >) componentClass , priority );
499514 newFeatureRegistrations .add (registration );
500515 }
501516 }
@@ -524,7 +539,7 @@ public CommonConfig loadFrom(final Configuration config) {
524539 this .enabledFeatureClasses .clear ();
525540
526541 componentBag .clear ();
527- resetRegistrations ();
542+ resetFeatureRegistrations ();
528543
529544 for (final Class <?> clazz : config .getClasses ()) {
530545 if (Feature .class .isAssignableFrom (clazz ) && config .isEnabled ((Class <? extends Feature >) clazz )) {
@@ -629,7 +644,7 @@ public void configureMetaProviders(InjectionManager injectionManager, ManagedObj
629644 // Next, register external meta objects
630645 configureExternalObjects (injectionManager , configuredExternals );
631646 // Configure all features
632- configureFeatures (injectionManager , new HashSet <>(), resetRegistrations (), finalizer );
647+ configureFeatures (injectionManager , new HashSet <>(), resetFeatureRegistrations (), finalizer );
633648 // Next, register external meta objects registered by features
634649 configureExternalObjects (injectionManager , configuredExternals );
635650 // At last, configure any new binders added by features
@@ -718,16 +733,17 @@ private void configureFeatures(InjectionManager injectionManager,
718733 if (providerModel != null ) {
719734 ProviderBinder .bindProvider (feature , providerModel , injectionManager );
720735 }
721- configureFeatures (injectionManager , processed , resetRegistrations (), managedObjectsFinalizer );
736+ configureFeatures (injectionManager , processed , resetFeatureRegistrations (), managedObjectsFinalizer );
722737 enabledFeatureClasses .add (registration .getFeatureClass ());
723738 enabledFeatures .add (feature );
724739 }
725740 }
726741 }
727742
728- private List <FeatureRegistration > resetRegistrations () {
743+ private List <FeatureRegistration > resetFeatureRegistrations () {
729744 final List <FeatureRegistration > result = new ArrayList <>(newFeatureRegistrations );
730745 newFeatureRegistrations .clear ();
746+ Collections .sort (result , (o1 , o2 ) -> o1 .priority < o2 .priority ? -1 : 1 );
731747 return result ;
732748 }
733749
0 commit comments