cemo koc opened SPR-11663 and commented

I would like to create some proxy beans based on interfaces. I will provide some basic examples to make clear.

Use case 1: Creating a proxy restful client based on interface

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Restful {
   String value() default "";
}

@Restful 
public interface MyRestClient {

  @Get("/events/{year}/{location}")
  EventList getEventsByYearAndLocation(int year, String location);

 }

Use case 2: Creating a proxy repository instance based on interfaces

@MyRepository // new annotation
public interface PersonRepository {
   List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
  List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}

In order to provide this functionality I had to dig many codes from Spring Data project and became little frustrated with result. I had to create 6-7 class and most of them are duplicated. As a result of my implementation basically I had to create a custom InstantiationAwareBeanPostProcessorAdapter to create beans with custom logic after registering them.

I would like to see a configuration mechanism for registering beans for abstract types dynamically. I was considering an API for component scanning such as ComponentScanProcessor. Each registered ComponentScanProcessor can decide about candidates.

This will help to reduce a fair amount codes in many projects even Spring Data which is creating repository beans from Interfaces.


Affects: 4.0.3

Issue Links: - #17399 ClassPathScanningCandidateComponentProvider doesn't respect AnnotationTypeFilter - #18794 @Configuration interface with Java 8 default methods (as a standalone artifact) - #16509 Spring-specific index file for component candidate classes - #19118 Classes with abstract @Lookup methods not registered in case of classpath scanning

3 votes, 6 watchers

Comment From: spring-projects-issues

cemo koc commented

Any chance for this issue? I believe that It will help a lot other frameworks based on Spring as well. For example currently I am trying to implement a library based on only Spring JDBC. I need to create some proxy instances as a result of component scan but strict nature of component scan is blocking. I am ready for any kind of help.

Comment From: spring-projects-issues

Juergen Hoeller commented

Alright, as per your comment on #15547, I'll consider this one for 4.2 as well. No promises yet, just moving it to a concrete timeframe for consideration :-)

Juergen

Comment From: spring-projects-issues

Juergen Hoeller commented

I'm afraid this might not make it into 4.2 RC1... too much on the plate still, and a rather hard deadline towards the end of May.

Juergen

Comment From: spring-projects-issues

Juergen Hoeller commented

Oliver Drotbohm, any current take from your side on what would make sense for Spring Data here? I'm happy to consider this for 5.0 still but I'd like to understand our use cases better.

From my perspective, we could let our component scanner register abstract classes as abstract bean definitions which will get ignored by the container by default. A regular BeanFactoryPostProcessor can then identify specific kinds of beans and modify their definitions accordingly, in particular flipping the abstract flag to false if it wants them to be actually created (after completing their bean metadata accordingly). This would be the easiest solution for the @Lookup case raised in #19118.

Comment From: spring-projects-issues

Juergen Hoeller commented

After discussions with the Spring Data team, we are not going to generally allow component scanning to pick up abstract types, and we won't provide an SPI at the scanner level either. Instead, in particular with 5.0's indexing mechanism, we actually recommend a separate scan attempt for specific interfaces, ideally combined with a post-processor that knows how to turn those interfaces into concrete components. If you'd like to have a nicer way to customize the scanner, we're definitely open to that. What does your current code look like there?