- Before we can understand the value of @Component, we must first understand a little bit about the Spring ApplicationContext. This is where Spring holds instances of objects that it has identified to be managed and distributed automatically. These are called beans. Bean management and the opportunity for dependency injection are some of Spring’s main features.
- Using the Inversion of Control principle, Spring collects bean instances from our application and uses them at the appropriate time. We can show bean dependencies to Spring without needing to handle the setup and instantiation of those objects.
- The ability to use annotations like @Autowired to inject Spring-managed beans into our application is a driving force for creating powerful and scalable code in Spring.
- @Component is an annotation that allows Spring to automatically detect our custom beans.
- In other words, without having to write any explicit code, Spring will:
- Scan our application for classes annotated with @Component
- Instantiate them and inject any specified dependencies into them
- Inject them wherever needed
However, most developers prefer to use the more specialized stereotype annotations to serve this function. @Controller, @Service and @Repository
Before we rely completely on @Component, we must understand that in and of itself, it’s only a plain annotation. The annotation serves the purpose of differentiating beans from other objects, such as domain objects. However, Spring uses the @ComponentScan annotation to actually gather them all into its ApplicationContext.
If we’re writing a Spring Boot application, it is helpful to know that @SpringBootApplication is a composed annotation that includes @ComponentScan. As long as our @SpringBootApplication class is at the root of our project, it will scan every @Component we define by default.
However, in the case that our @SpringBootApplication class cannot be at the root of our project or we want to scan outside sources, we can configure @ComponentScan explicitly to look in whatever package we specify, as long as it exists on the classpath.
Example :
BirdLife.java , this class is marked as component
package GradleDemo;
import org.springframework.stereotype.Component;
@Component
public class BirdLife {
public void haveFood() {
System.out.println(" Hedwig is eating food");
}
}
App.java, (Run this class as a Java application)
package GradleDemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class App {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(App.class, args);
BirdLife birdLife = applicationContext.getBean(BirdLife.class);
birdLife.haveFood();
}
}
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.0.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.7.RELEASE'
}
repositories {
jcenter()
}
dependencies {
implementation 'com.google.guava:guava:28.0-jre'
testImplementation 'junit:junit:4.12'
implementation 'org.springframework.boot:spring-boot-dependencies:2.0.5.RELEASE'
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
components {
withModule('org.springframework:spring-beans') {
allVariants {
withDependencyConstraints {
it.findAll { it.name == 'snakeyaml' }.each { it.version { strictly '1.19' } }
}
}
}
}
}
bootJar {
mainClassName = 'GradleDemo.App'
}
task runJar{
dependsOn 'assemble'
dependsOn 'jar'
doLast{
javaexec {
main="-jar";
args = [
"build/libs/"+rootProject.name+".jar"
]
}
}
}
Reference :