Announcement Announcement Module
Collapse
No announcement yet.
Injecting / autowiring collection provider [to implement contribution] Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Injecting / autowiring collection provider [to implement contribution]

    Hi, I've used spring from long time and I really like that Spring from version 2.5 started using annotations.

    I implement contributions for my application and I found inconsistent behaviour for Provider/ObjectFactory. There are defined classes for different contributions:

    Code:
    @Contribute("rest")
    @Named("bean-contrib2a")
    public class Contrib2A implements ContribRest { ... }
    
    @Contribute("rest")
    @Named("bean-contrib2b")
    public class Contrib2B { ... }
    
    @Contribute("non-rest")
    @Named("bean-contrib3a")
    public class Contrib3A implements ContribRest { ... }
    
    @Contribute("non-rest")
    @Named("bean-contrib3b")
    public class Contrib3B { ... }
    Code to show injecting scenario looks like that:

    Code:
    @Named("applicationRest")
    public class ApplicationRest extends Application {
    
        private List<ContribRest> contrib2;
        private List<ContribRest> contrib4;
    
        private ObjectFactory<List<ContribRest>> ofContrib2;
        private ObjectFactory<List<ContribRest>> ofContrib4;
    
        private Provider<List<ContribRest>> pvdContrib2;
        private Provider<List<ContribRest>> pvdContrib4;
    
        @Inject
        public void setContrib2(@Contribute("rest") List<ContribRest> contrib2) {
            this.contrib2 = contrib2;
        }
    
        @Autowired(required = false)
        public void setContrib4(@Contribute("other") List<ContribRest> contrib4) {
            this.contrib4 = contrib4;
        }
    
        @Inject
        public void setOfContrib2(@Contribute("rest") ObjectFactory<List<ContribRest>> ofContrib2) {
            this.ofContrib2 = ofContrib2;
        }
    
        @Autowired(required = false)
        public void setOfContrib4(@Contribute("other") ObjectFactory<List<ContribRest>> ofContrib4) {
            this.ofContrib4 = ofContrib4;
        }
    
        @Inject
        public void setPvdContrib2(@Contribute("rest") Provider<List<ContribRest>> pvdContrib2) {
            this.pvdContrib2 = pvdContrib2;
        }
    
        @Autowired(required = false)
        public void setPvdContrib4(@Contribute("other") Provider<List<ContribRest>> pvdContrib4) {
            this.pvdContrib4 = pvdContrib4;
        }
    Injection finish with that result:

    Code:
    INFO contrib2=[Contrib2A@51a19458] -
    INFO contrib4=null
    ERROR ofContrib2=No unique bean of type [java.lang.Object] is defined: expected single matching bean but found 2: [bean-contrib2b, bean-contrib2a]
    INFO ofContrib4=null
    ERROR pvdContrib2=No unique bean of type [java.lang.Object] is defined: expected single matching bean but found 2: [bean-contrib2b, bean-contrib2a] - 
    INFO pvdContrib4=null
    Injecting list looks correct - classes with other contribution and type are filtered and only Contrib2A is injected. Unfortunately injecting Provider or ObjectFactory tries to inject List a not all beans for this list.

    Is it bug in injecting Provider/ObjectFactory or expected behaviour? How is it guaranteed to work in future?

    Even I can accept that it is searching list with specified name but how can I provide this list with all instances contributed (scanned) without manually defining list in XML.

    BR//Kamil Demecki
Working...
X