Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-5192

@LookupMethod annotation for use with component scanning

    Details

    • Type: New Feature
    • Status: Closed
    • Priority: Major
    • Resolution: Complete
    • Affects Version/s: None
    • Fix Version/s: 4.1 RC2
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      true

      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.

      1. LookupMethod.java
        0.3 kB
        Casey Butterworth
      2. LookupMethod.java
        0.4 kB
        Casey Butterworth
      3. LookupMethodAnnotationBeanPostProcessor.java
        2 kB
        Casey Butterworth

        Issue Links

          Activity

          Hide
          juergen.hoeller Juergen Hoeller added a comment -

          I'm afraid @Bean methods are not meant to be called as factory methods from outside. They are rather designed as a factory method callback mechanism within the container, with the container calling them when a particular bean needs to be created. BeanFactory.getBean is indeed the primary entry point from outside.

          Since you mentioned it, why specifically do you feel stuck on Spring 3.2.x? Spring 4.x is still runtime-compatible with Servlet 2.5 containers, so does that mean you're on Servlet 2.4? Which application server is it in your case?

          Show
          juergen.hoeller Juergen Hoeller added a comment - I'm afraid @Bean methods are not meant to be called as factory methods from outside. They are rather designed as a factory method callback mechanism within the container, with the container calling them when a particular bean needs to be created. BeanFactory.getBean is indeed the primary entry point from outside. Since you mentioned it, why specifically do you feel stuck on Spring 3.2.x? Spring 4.x is still runtime-compatible with Servlet 2.5 containers, so does that mean you're on Servlet 2.4? Which application server is it in your case?
          Hide
          mirak mirak added a comment -

          This is a Jonas 4 something based on tomcat5, which supports servlet 2.4 only. I realised that when I tried to used spring 4.x . We are supposed to migrate to Websphere 8.5.5.4 someday ...

          Regarding the BeanFactory.getBean what we do actually is something like

          	@Bean
          	public House houseFactory() {
          		return new HouseFactory() {
           
          			@Override
          			public HouseFactory House house(String name, int windows) {
          				return ctx.getBean("house", name, windows );
          			}
           
          		};
          	}
          

          We don't expose the spring api in our business objects, and if a constructor changes, we know the impacts at compile time.
          This is what looked interesting in being able to directly call the @Bean methods.
          At first I though it was a bug because getBean manage to call this @Bean method in some way.

          Show
          mirak mirak added a comment - This is a Jonas 4 something based on tomcat5, which supports servlet 2.4 only. I realised that when I tried to used spring 4.x . We are supposed to migrate to Websphere 8.5.5.4 someday ... Regarding the BeanFactory.getBean what we do actually is something like @Bean public House houseFactory() { return new HouseFactory() {   @Override public HouseFactory House house(String name, int windows) { return ctx.getBean( "house" , name, windows ); }   }; } We don't expose the spring api in our business objects, and if a constructor changes, we know the impacts at compile time. This is what looked interesting in being able to directly call the @Bean methods. At first I though it was a bug because getBean manage to call this @Bean method in some way.
          Hide
          mirak mirak added a comment -

          I think I will emulate the spring 4.x @Lookup method by create a @Lookup annotation, and use an around aspect, on the will call BeanFactory.getBean( ... ) with the appropriate parameters.
          This way we will be ready for spring 4.x, and just remove the aspect declaration.

          Show
          mirak mirak added a comment - I think I will emulate the spring 4.x @Lookup method by create a @Lookup annotation, and use an around aspect, on the will call BeanFactory.getBean( ... ) with the appropriate parameters. This way we will be ready for spring 4.x, and just remove the aspect declaration.
          Hide
          mirak mirak added a comment -

          By the way I realised it's possible to also use an interface that implements the @Lookup method and the @Bean method in the @Configuration file, to be sure to have the same parameters.

          Show
          mirak mirak added a comment - By the way I realised it's possible to also use an interface that implements the @Lookup method and the @Bean method in the @Configuration file, to be sure to have the same parameters.
          Hide
          mirak mirak added a comment -

          >> I'm afraid @Bean methods are not meant to be called as factory methods from outside. They are rather designed as a factory method callback mechanism within the container, with the container calling them when a particular bean needs to be created.

          It seems this JIRA https://jira.spring.io/browse/SPR-12443 fixes my issue in Spring 4.1.3 .
          Maybe you had time to reflect on this, but what you say now about user call of @Bean methods, seems a bit more cautious than what you commented back then here https://jira.spring.io/browse/SPR-12443

          Show
          mirak mirak added a comment - >> I'm afraid @Bean methods are not meant to be called as factory methods from outside. They are rather designed as a factory method callback mechanism within the container, with the container calling them when a particular bean needs to be created. It seems this JIRA https://jira.spring.io/browse/SPR-12443 fixes my issue in Spring 4.1.3 . Maybe you had time to reflect on this, but what you say now about user call of @Bean methods, seems a bit more cautious than what you commented back then here https://jira.spring.io/browse/SPR-12443

            People

            • Assignee:
              juergen.hoeller Juergen Hoeller
              Reporter:
              casey.butterworth Casey Butterworth
              Last updater:
              mirak
            • Votes:
              37 Vote for this issue
              Watchers:
              33 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since last comment:
                4 weeks, 3 days ago