Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I extend an @Component and create another @Component class and make only one available at a time?

I have a library jar which I want to provide to a number of applications. The behavior I want is to create a common spring component class in the library. If in the applications, the same component is not extended then use the common component; if it's extended in the app, then use the extended component (child class). Is this possible? - Create CommonComponent only if a child for that class doesn't exist.

I am using Java 1.8, Springboot2.0

Created class in library:

@Component
public class CommonComponent{}

In one of the child apps using the library, I added a child component:

@Component
public class ChildComponent extends CommonComponent{}

I expected one component ChildComponent created; but in the above scenario 2 components - CommonComponent and ChildComponent are created.

like image 727
jishamenon Avatar asked Jun 13 '19 12:06

jishamenon


2 Answers

One way you could do this is to take advantage of the @ConditionalOnMissingBean annotation that Spring Boot has. When combined with a bean definition in a @Configuration class, we can tell Spring to only define our bean if it doesn't already have one.

This is untested:

@Configuration
public class CustomComponentConfiguration {

    @ConditionalOnMissingBean(CustomComponent.class)
    @Bean
    public CustomComponent customComponent() {
        return new CustomComponent();
    }
}

In this example, when our @Configuration runs, Spring determines if there is any other bean that is a CustomComponent. If not, it executes the customComponent() method and defines whatever bean you return. So if somebody else defines a ChildComponent, this method will not get called.

like image 124
Todd Avatar answered Nov 15 '22 20:11

Todd


when you are creating the child component put @Primary annotation

Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency

so you'll have

@Primary
@Component
public class ChildComponent extends CommonComponent { /* ... */ }

and in your services autowire CommonComponent type and spring will inject ChildComponent or CommonComponent

like image 3
Adrian Avatar answered Nov 15 '22 22:11

Adrian