Spliterash
Spliterash

Reputation: 331

Spring create generic service multiple times using generic in constructor

I have a service that uses some object as a generic

@Component
@RequiredArgsConstructor
public class SomeGenericService<T extends Base> {
    private final T base;

    public void someWork(String info) {
        base.someAction(info);
    }
}

I also have 3 Base implementations marked with @Component(Base1, Base2, Base3)

I want spring itself to create a service with the generic it needs, for the following example

@Component
@RequiredArgsConstructor
public class Runner implements CommandLineRunner {
    private final SomeGenericService<Base1> s1;
    private final SomeGenericService<Base2> s2;
    private final SomeGenericService<Base3> s3;

    @Override
    public void run(String... args) throws Exception {
        String someString = "text";

        s1.someWork(someString);
        s2.someWork(someString);
        s3.someWork(someString);
    }
}

But after the launch, the spring does not understand what I want from it.

Parameter 0 of constructor in SomeGenericService required a single bean, but 3 were found:
    - base1: defined in file [Base1.class]
    - base2: defined in file [Base2.class]
    - base3: defined in file [Base3.class]

Is it possible to set this to automatic, without manually configuring it via the @Bean annotation for each service?

Upvotes: 3

Views: 476

Answers (1)

Nicolas Garcia
Nicolas Garcia

Reputation: 48

You need to define how those beans should be injected. It's a good practice to have some @Configurations for this purpose. Something like:

 @Configuration
 @Import({
            Base1.class,
            Base2.class,
            Base3.class
    })
    public class SomeConfig {
        @Bean
        SomeGenericService<Base1> someGenericService1() {
            return new SomeGenericService(new Base1());
        }
        @Bean
        SomeGenericService<Base2> someGenericService2() {
            return new SomeGenericService(new Base2());
        }
        @Bean
        SomeGenericService<Base3> someGenericService3() {
            return new SomeGenericService(new Base3());
        }
    }

Upvotes: 1

Related Questions