3

I have a spring config where I define hundreds of actions which extend MyAction. I have a pool where an execution service can look up actions. I can't use the appContext directly because each action has one or more "keys" which the execution service will use and pool cuts that dependency.

So the pool must be able to collect all beans of type MyAction (or rather beans that extend MyAction).

The method ApplicationContext.getBeansOfType() seems to do what I need but when can I safely call it?

It would be great if I could call it in a @PostConstruct method but is it guaranteed that the bean factory has seen added each and every bean from the config at that time?

Note: Almost all of my beans are @Lazy

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820

2 Answers2

2

You could use injection by constructor and passing a Collection of yours MyAction

Something like

 @Component
 public class Foo {
     private final Set<MyAction> myActions;

     @Inject
     public Foo(Set<MyAction> myActions) { this.myActions = myActions; }
 }

or

 public class Foo {
     private Set<MyAction> myActions;

     @Inject
     public void setMyActions(Set<MyAction> myActions) { this.myActions = myActions; }
 }

Spring will take care of creating the set with all beans that extends MyAction.

In the first case, they are injected by constructor, you can safely use them in any method.

In the second case, Spring will eventually call the setter. You can either do any post processing in the setter or add a @PostConstruct method that works on myActions.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
Caesar Ralf
  • 2,203
  • 1
  • 18
  • 36
  • This looks promising. Let me write a test case. – Aaron Digulla Jan 09 '13 at 13:49
  • Is there a way to create this bean without doing a component scan? – Aaron Digulla Jan 09 '13 at 13:57
  • 1
    @AaronDigulla You say `Foo`? You can "create it" via xml and still using the `@Inject` or `@Autowired` annotation for your constructor. You will still be needing to scan classes with `MyAction` or declare them in the XML. Another requirement (that you need for `@PostConstruct` also) is activating the annotation-config scan like at your XML. – Caesar Ralf Jan 09 '13 at 14:02
  • You're welcome. Note: I like to avoid using XML based configurations. It would be nice when a bean method in a `@Configuration` could return a type and Spring would do the `new` for me. – Aaron Digulla Jan 09 '13 at 14:16
1

Try to use ListableBeanFactory like this. Also here is API documentation. Method getBeansOfType has parameter allowEagerInit which forces eager init of lazy object.

Community
  • 1
  • 1
partlov
  • 13,789
  • 6
  • 63
  • 82