Spring Framework
  1. Spring Framework
  2. SPR-5192

@LookupMethod annotation for use with component scanning

    Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: Waiting for Triage
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      I have recently started some work on an @LookupMethod annotation to be used in the following situation:

      • A prototype scoped bean needs to be used within a singleton
      • The singleton was created using component scanning

      Currently the most obvious solution would be to forgo component scanning for the singleton and define the lookup-method in the ApplicationContext XML or using spring-java-config, e.g:

      <!-- this could also be created using component scanning -->
      <bean id="myPrototype" class="sample.MyPrototype" scope="prototype"/>
      
      <bean id="mySingleton" class="sample.MySingleton">
        <lookup-method name="createMyPrototype" bean="myPrototype"/>
      </bean>
      

      However, since I've been using component scanning with 2.5, it doesn't feel right defining the wiring outside of the components, and it would be ideal if we could do something like the following:

      @Component
      public abstract class MySingleton {
         @LookupMethod(beanRef = "myPrototype")
         protected abstract MyPrototype createMyPrototype();
      }
      
      @Component
      public class MyPrototype {}
      

      It would be even better if @LookupMethod could work in conjunction with autowiring (by type), but that can be a subsequent feature request.

      I've started to implement a solution and will attach shortly.

        Activity

        Hide
        Marko Topolnik added a comment -

        I would just like to point out that the bean class does not need to be abstract – in fact, I have never used it that way. This is the way I do it:

        MySingleton.java
        public class MySingleton {
          protected MyPrototype createMyPrototype() {
            throw new UnsupportedOperationException("Spring should override this lookup method");
          }
        }
        
        Show
        Marko Topolnik added a comment - I would just like to point out that the bean class does not need to be abstract – in fact, I have never used it that way. This is the way I do it: MySingleton.java public class MySingleton { protected MyPrototype createMyPrototype() { throw new UnsupportedOperationException( "Spring should override this lookup method" ); } }
        Hide
        Alexis Torres added a comment -

        Hello,

        I was really interested in that option till I understood @ScopedProxy annotation.
        The elegant work around is making the singleton autowire a ScopeProxy which has a prototype behavior.

        Not saying that this shouldn't be implemented but maybe priority is not as important.

        Show
        Alexis Torres added a comment - Hello, I was really interested in that option till I understood @ScopedProxy annotation. The elegant work around is making the singleton autowire a ScopeProxy which has a prototype behavior. Not saying that this shouldn't be implemented but maybe priority is not as important.
        Hide
        Dmitry Katsubo added a comment -

        I would vote for @Autowired to work for such lookup methods naturally, so there is no need to introduce new annotation (@LookupMethod):

        @Autowired
        protected MyPrototype createMyPrototype() { ... }
        
        Show
        Dmitry Katsubo added a comment - I would vote for @Autowired to work for such lookup methods naturally, so there is no need to introduce new annotation ( @LookupMethod ): @Autowired protected MyPrototype createMyPrototype() { ... }
        Hide
        Alexey Fansky added a comment -

        So are there any solutions for this?

        Show
        Alexey Fansky added a comment - So are there any solutions for this?
        Hide
        Phil Webb added a comment -

        Generally the preferred solution with this type of problem is to use the javax.inject.Provider interface from JSR-330. It tends to result in clearer code and removes the need to throw the UnsupportedOperationException.

        public class MySingleton {
        
          @Autowired
          private Provider<MyPrototype> myPrototype;
        
          public void operation() {
            MyPrototype instance = myPrototype.get();
            // do something with the instance
          }
        
        }
        
        Show
        Phil Webb added a comment - Generally the preferred solution with this type of problem is to use the javax.inject.Provider interface from JSR-330. It tends to result in clearer code and removes the need to throw the UnsupportedOperationException. public class MySingleton { @Autowired private Provider<MyPrototype> myPrototype; public void operation() { MyPrototype instance = myPrototype.get(); // do something with the instance } }

          People

          • Assignee:
            Juergen Hoeller
            Reporter:
            Casey Butterworth
            Last updater:
            Chris Beams
          • Votes:
            37 Vote for this issue
            Watchers:
            34 Start watching this issue

            Dates

            • Created:
              Updated:
              Days since last comment:
              1 year, 18 weeks, 6 days ago