Spring Framework
  1. Spring Framework
  2. SPR-5583

ComponentScanBeanDefinitionParser - enable BeanDefinition factory registration similar to TypeFilter registration

    Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 2.5.6, 3.0 M1, 3.0 M2
    • Fix Version/s: Waiting for Triage
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      true

      Description

      I'd like to enable Spring's component scanner (<context:component-scan .../>) to look for all Interfaces annotated with the @Service annotation.

      Then for remoting scenarios, the client tier Scanner could find all interfaces annotated with @Service and then auto-generate remoting proxy stubs. The server tier Scanner can find the same annotated interfaces and auto-generate the remoting exporters. All of this would be really slick and work based on just the @Service annotation on one or more interfaces.

      The problem currently is that the @Service annotation is really expected to be used within Class definitions - not Interfaces (indeed the ClassPathScanningCandidateComponentProvider#isCandidateComponent(AnnotatedBeanDefinition beanDefinition) method explicitly discards Interfaces by default).

      This is an important distinction because in most remoting environments, the actual business implementations of an Interface will not be shipped to the client VM, so annotating the implementation class won't work.

      For example, in a business-tier environment using JMS remoting, 2 BeanDefinitions could be registered based on a single discovered @Service annotated Interface: an InvocationListener and a ServiceExporter. In the client-tier environment, a BeanDefinition that specifies some service ProxyFactoryBean would be registered.

      Example config:

      <context:component-scan base-package="org.example">
      <context:include-bdfactory ref="myBeanDefinitionFactory"/>
      </context:component-scan>

      Where 'myBeanDefinitionFactory' would implement an interface that has a method that, given a MetadataReader returns a Collection<BeanDefinition>, i.e.

      BeanDefinitionFactory#createBeanDefinitions(MetadataReader metadataReader) : Collection<BeanDefinition>

      Then in ClassPathScanningCandidateComponentProvider (somewhere between lines 190 and 201):

      Collection<BeanDefinition> created= registeredBeanDefinitionFactory.createBeanDefinitions(locatedMetadataReader);
      ...
      candidates.addAll(created);

        Activity

        Hide
        Les Hazlewood added a comment -

        The default implementation of this factory interface would just return a Collection with a single ScannedGenericBeanDefinition instance to retain the current behavior.

        Show
        Les Hazlewood added a comment - The default implementation of this factory interface would just return a Collection with a single ScannedGenericBeanDefinition instance to retain the current behavior.
        Hide
        Les Hazlewood added a comment -

        This same technique could be used for auto-exposing Web Services or REST endpoints based on just an annotated Interface as well. Many possibilities...

        Show
        Les Hazlewood added a comment - This same technique could be used for auto-exposing Web Services or REST endpoints based on just an annotated Interface as well. Many possibilities...

          People

          • Assignee:
            Unassigned
            Reporter:
            Les Hazlewood
            Last updater:
            Chris Beams
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Days since last comment:
              5 years, 6 weeks ago