How do I define and inject dependencies using annotations in Spring?
In Spring, you can define and inject dependencies using annotations, which simplifies the process of configuring beans and their relationships. Here’s how you can do it step by step: 1. Define a Dependency with @Component To define a class as a Spring-managed component (or bean), you annotate it with @Component, which makes the class eligible […]
Artikel oleh Wayan · Sumber: Kode Java ↗
Terjemahan artikel ini belum tersedia. Isi asli ditampilkan.
In Spring, you can define and inject dependencies using annotations, which simplifies the process of configuring beans and their relationships. Here’s how you can do it step by step:
1. Define a Dependency with @Component
To define a class as a Spring-managed component (or bean), you annotate it with @Component, which makes the class eligible for dependency injection.
package org.kodejava.spring;
import org.springframework.stereotype.Component;
@Component
public class MyDependency {
public void doSomething() {
System.out.println("Dependency logic executed.");
}
}
Here, @Component tells Spring to manage the lifecycle of this class as a bean.
2. Inject the Dependency with @Autowired
You can inject dependencies into another class by using the @Autowired annotation. It can be applied to:
- Field injection
- Constructor injection (recommended)
- Setter injection
A. Field Injection
package org.kodejava.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyService {
@Autowired // Spring automatically injects the MyDependency bean here
private MyDependency myDependency;
public void performTask() {
myDependency.doSomething();
}
}
B. Constructor Injection (Recommended)
Constructor injection is preferred as it makes the dependencies immutable and facilitates better testing.
package org.kodejava.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyService {
private final MyDependency myDependency;
@Autowired
public MyService(MyDependency myDependency) {
this.myDependency = myDependency;
}
public void performTask() {
myDependency.doSomething();
}
}
Note: From Spring 4.3 onward, if a class has only one constructor, the @Autowired annotation is optional since Spring will automatically use that constructor to inject dependencies.
C. Setter Injection
package org.kodejava.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyService {
private MyDependency myDependency;
@Autowired
public void setMyDependency(MyDependency myDependency) {
this.myDependency = myDependency;
}
public void performTask() {
myDependency.doSomething();
}
}
3. Marking Other Components
Instead of using @Component, Spring provides additional stereotype annotations for specific roles, although they work similarly. These are:
@Service: Used for service classes.@Repository: Used for data access/DAO components.@Controller: Used for Spring MVC controllers.
Example:
import org.springframework.stereotype.Service;
@Service
public class MyService {
public void executeService() {
System.out.println("Executing service logic...");
}
}
4. Enable Component Scanning
To ensure Spring automatically discovers and registers your components, you need to enable component scanning using the @ComponentScan annotation in your configuration class.
Example configuration class:
package org.kodejava.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "org.kodejava")
public class AppConfig {
}
Alternatively, if you are using Spring Boot, component scanning is enabled automatically for classes within the same package or sub-packages of the main application class annotated with @SpringBootApplication.
5. Example of Application Setup
Here’s a complete example:
Dependency
package org.kodejava.spring;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldService {
public String sayHello() {
return "Hello, World!";
}
}
Service
package org.kodejava.spring;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class GreetingService {
private final HelloWorldService helloWorldService;
@Autowired
public GreetingService(HelloWorldService helloWorldService) {
this.helloWorldService = helloWorldService;
}
public void printGreeting() {
System.out.println(helloWorldService.sayHello());
}
}
Main Application
package org.kodejava.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Application {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
GreetingService greetingService = context.getBean(GreetingService.class);
greetingService.printGreeting();
}
}
Configuration
package org.kodejava.spring;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "org.kodejava")
public class AppConfig {
}
Summary of Annotations:
@Component: Marks a class as a Spring bean.@Service: A specialization of@Component, typically used for service-layer classes.@Repository: A specialization of@Component, used for DAO/repository classes.@Controller: A specialization of@Component, used for Spring MVC controllers.@Autowired: Marks a dependency to be automatically injected by Spring.@ComponentScan: Specifies the base package(s) for scanning components.
This approach makes dependency management clean and reduces boilerplate code compared to XML-based configurations.
Maven Dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.2.6</version>
</dependency>
