@Aurowired는 스프링 프레임워크에서 의존성 주입(Dependency Injection)을 자동화하기 위해 제공되는 어노테이션이다.
스츠링 컨테이너에 의해 관리되는 빈(bean)간의 의존성을 자동으로 해결하고 주입하도록 지시하는 역할을 한다.
src/main/resources 폴더 아래 xml파일을 놓는다.
해당 파일을 생성하는 방법은 아래와 같다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<!-- 어노테이션 설정된 클래스의 객체 생성을 위한 설정
1. 네임스페이스 추가 : context(xmlns:context)
2. <context:component-scan> 태그 설정으로 찾을 위치 지정
- base-package 속성 : 컴포넌트 어노테이션 찾을 위치 지정
(설정된 패키지 포함 + 하위 패키지 모두 검색)
-->
<context:component-scan base-package="di_annotation_xml"></context:component-scan>
<bean id="sonySpeaker" class="di_annotation_xml.SonySpeaker" />
<!-- <bean id="appleSpeaker" class="di_annotation_xml.AppleSpeaker" /> -->
</beans>
xmlns: 스프링 프레임워크의 빈 구성 및 어노테이션 지원을 위한 네임스페이스를 선언한다.xsi:schemaLocation: 네임스페이스가 참조하는 스키마의 위치를 지정한다. 이를 통해 XML 문서의 구조가 해당 스키마에 맞는지 검증할 수 있다.xmlns:context: context 네임스페이스를 통해 어노테이션 기반 설정을 할 수 있게 한다.@Component, @Service, @Repository, @Controller 등의 스테레오타입 어노테이션이 붙은 클래스를 자동으로 스프링 컨테이너에 빈으로 등록한다.<bean> 태그)
@Autowired
private MyService myService;
필드 주입은 다음과 같은 과정을 통해 이루어진다
예시
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyService {
// 필드 주입 사용
@Autowired
private MyRepository myRepository;
public void performAction() {
myRepository.doSomething();
}
}
필드 주입은 특히 간단하고 변경이 자주 발생하지 않는 의존성에 적합하나, 더 복잡하거나 테스트가 중요한 환경에서는 생성자 주입이 더 권장된다. 이는 생성자를 통해 모든 의존성이 명시적으로 제공되고, 필요한 모든 의존성이 누락되지 않도록 강제하기 때문이다.
@Autowired
public MyComponent(MyService myService) {
this.myService = myService;
}
아래의 예제에서 UserService 클래스는 UserRepository에 대한 의존성을 갖고 있다. 이 의존성은 생성자를 통해 주입된다. 이 방식을 사용함으로써, UserService인스턴스가 생성될 때 반드시 UserRepository 인스턴스가 필요함을 보장할 수 있다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
// 생성자 주입
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void registerUser(User user) {
userRepository.save(user);
}
}
다음 예제에서 NotificationService 클래스는 EmailService와 SMSService라는 두 가지 의존성을 갖고 있다. 이 두 서비스는 모두 알림을 보내는 방법을 제공하지만, 각기 다른 채널을 통해 이루어진다. 생성자를 통해 두 서비스 모두 주입되므로, NotificationService는 필요에 따라 적절한 서비스를 사용할 수 있다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class NotificationService {
private final EmailService emailService;
private final SMSService smsService;
// 두 의존성을 생성자를 통해 주입
@Autowired
public NotificationService(EmailService emailService, SMSService smsService) {
this.emailService = emailService;
this.smsService = smsService;
}
public void sendEmailNotification(String message) {
emailService.sendEmail(message);
}
public void sendSMSNotification(String message) {
smsService.sendSMS(message);
}
}
위처럼 Autowired 를 적용했을 경우, 기본 생성자를 통해 선언할 수 없다.
스프링에서 생성자 주입을 사용하면 명시적으로 선언된 생성자를 사용해야 하며, 이 경우 파라미터가 없는 기본 생성자를 통해 객체를 생성할 수 없다. 이는 다음과 같은 이유로 설계적인 이점을 제공한다
물론 필요에 따라서 생성하게 만들 수도 있고, 그러면 null이 저장되지만... 그러나 일반적인 스프링 사용에서는 생성자 주입만을 사용하여 모든 의존성을 명시적으로 주입하는 것이 더 권장된다.
세터 메서드에 '@Autowired' 를 붙여 의존성을 주입할 수 있다.
@Autowired
public void setMyService(MyService myService) {
this.myService = myService;
}
세터 메서드 주입(setter injection)은 스프링 프레임워크에서 객체의 의존성을 주입하는 또 다른 방법이다. 이 방식은 객체가 생성된 후에도 해당 객체의 의존성을 변경할 수 있게 해준다. (생성자 주입은 변경이 불가능하지만, 세터는 가능!!) 세터 메서드 주입을 사용하면, 의존성 주입을 위한 특정 메서드(세터)에 @Autowired 애노테이션을 붙여 스프링이 자동으로 해당 타입의 빈을 찾아 메서드를 통해 주입하도록 합니다.
@Autowired 애노테이션을 적용하여 스프링에 의존성을 자동으로 주입하도록 지시한다.아래의 코드 예시에서는
EmailService라는 의존성을 가진NotificationService클래스를 살펴보겠다.NotificationService는 이메일 알림 기능을 제공하며,EmailService는 이메일을 전송하는 로직을 포함하고 있다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class NotificationService {
private EmailService emailService;
// 세터 메서드에 @Autowired 적용
@Autowired
public void setEmailService(EmailService emailService) {
this.emailService = emailService;
}
public void sendNotification(String message) {
emailService.sendEmail(message);
}
}
// EmailService 클래스
import org.springframework.stereotype.Service;
@Service
public class EmailService {
public void sendEmail(String message) {
System.out.println("Sending email with message: " + message);
}
}
장점
@Autowired(required = false)를 사용하면, 해당 타입의 빈이 없어도 오류가 발생하지 않는다.단점
세터 메서드 주입은 스프링에서 의존성 주입을 구현할 때 유용한 옵션 중 하나이다. 그러나 객체의 불변성을 중시하거나, 모든 의존성이 객체 생성 시점에 제공되어야 하는 경우 생성자 주입을 사용하는 것이 더 적합할 수 있다. 선택적 의존성이 필요하거나, 의존성을 변경이 필요한 경우엔 세터 메서드를 쓰는 것의 이점이 더 크다고 할 수 있다.
특정 메서드에 '@Autowired' 를 적용해 필요한 의존성을 메서드 매개변수에 전달할 수 있다.
@Autowired
public void configure(MyService myService, MyRepository myRepository) {
// 주입된 객체 사용
}
일반 메서드 주입(Method Injection)은 스프링에서 특정 메서드에 @Autowired 애노테이션을 사용하여 필요한 의존성을 주입하는 방식dㅣ다. 이 방법은 필드나 생성자 주입과는 다르게, 의존성이 필요한 특정 메서드에서만 의존성을 주입받을 수 있다. 이것은 특정한 설정 또는 초기화 작업이 필요할 때 유용하게 사용될 수 있다.
스프링 컨테이너는 클래스 내에 @Autowired가 적용된 모든 메서드를 찾고, 해당 메서드에 필요한 파라미터 타입의 빈을 찾아 자동으로 주입한다. 이 과정은 객체의 생성과 초기화 이후에 발생한다.
설정 클래스와 사용 클래스 정의
ConfigManager 클래스가 필요한 DatabaseConfig와 NetworkConfig 설정을 받아 초기화하는 과정을 거치는 경우를 생각해보자.
// Config 클래스 정의
@Component
public class DatabaseConfig {
public String getUrl() {
return "jdbc:mysql://localhost:3306/mydb";
}
}
@Component
public class NetworkConfig {
public String getBaseUrl() {
return "http://api.example.com";
}
}
// ConfigManager 클래스 정의
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ConfigManager {
private String dbUrl;
private String baseUrl;
// 일반 메서드 주입
@Autowired
public void setupConfig(DatabaseConfig dbConfig, NetworkConfig netConfig) {
this.dbUrl = dbConfig.getUrl();
this.baseUrl = netConfig.getBaseUrl();
initializeResources();
}
private void initializeResources() {
System.out.println("Database URL: " + dbUrl);
System.out.println("Base URL: " + baseUrl);
// 이곳에서 추가적인 초기화 로직 수행
}
}
일반 메서드 주입은 설정이나 초기화가 복잡한 경우, 또는 특정 조건에서만 의존성이 필요한 경우에 매우 유용하다. 그러나 모든 의존성 관리가 명확히 보장되어야 하는 경우, 생성자 주입이 더 적합할 수 있다. 이를 통해 클래스가 항상 완전히 초기화된 상태로 유지되도록 할 수 있다.
required속성을 false로 설정하면 주입하려는 빈이 없을 경우에도 예외를 발생시키지 않고 null로 주입한다.
@Autowired(required = false)
private OptionalService optionalService;
여러 빈이 같은 타입을 가지고 있을 경우, @Qualifier를 함께 사용하여 특정 빈을 명시적으로 지정할 수 있다.
@Autowired
@Qualifier("specificService")
private MyService myService;
@Autowired 는 스프링에서 의존성 주입을 간단하게 처리하기 위해 필수적인 애노테이션이다. 이 애노테이션을 사용하면 코드의 결합도를 줄이고 객체 생성과 관리의 복잡도를 낮출 수 있어 개발자가 생산적으로 코딩할 수 있다.