Loading...
Spring Framework Reference Documentation 7.0.2의 Using JSR 330 Standard Annotations의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
Spring은 JSR-330 표준 어노테이션(Dependency Injection)을 지원합니다. 이러한 어노테이션은 Spring 어노테이션과 동일한 방식으로 스캔됩니다. 이를 사용하려면, 관련 jar를 클래스패스에 포함해야 합니다.
Maven을 사용하는 경우, jakarta.inject 아티팩트는 표준 Maven
리포지토리
(https://repo.maven.apache.org/maven2/jakarta/inject/jakarta.inject-api/2.0.0/)에서
사용할 수 있습니다.
pom.xml 파일에 다음 의존성을 추가할 수 있습니다:
1<dependency> 2 <groupId>jakarta.inject</groupId> 3 <artifactId>jakarta.inject-api</artifactId> 4 <version>2.0.0</version> 5</dependency>
@Inject와 @Named를 사용한 의존성 주입@Autowired 대신에, 다음과 같이 @jakarta.inject.Inject를 사용할 수 있습니다:
1import jakarta.inject.Inject; 2 3public class SimpleMovieLister { 4 5 private MovieFinder movieFinder; 6 7 @Inject 8 public void setMovieFinder(MovieFinder movieFinder) { 9 this.movieFinder = movieFinder; 10 } 11 12 public void listMovies() { 13 this.movieFinder.findMovies(...); 14 // ... 15 } 16}
1import jakarta.inject.Inject 2 3class SimpleMovieLister { 4 5 @Inject 6 lateinit var movieFinder: MovieFinder 7 8 fun listMovies() { 9 movieFinder.findMovies(...) 10 // ... 11 } 12}
@Autowired와 마찬가지로, @Inject는 필드 레벨, 메서드 레벨
그리고 생성자 인자 레벨에서 사용할 수 있습니다. 더 나아가, 주입 지점을
Provider로 선언하여, 더 짧은 스코프의 빈에 대한 온디맨드 액세스나
Provider.get() 호출을 통한 다른 빈에 대한 지연 액세스를 허용할 수 있습니다.
다음 예제는 앞선 예제의 변형을 제공합니다:
1import jakarta.inject.Inject; 2import jakarta.inject.Provider; 3 4public class SimpleMovieLister { 5 6 private Provider<MovieFinder> movieFinder; 7 8 @Inject 9 public void setMovieFinder(Provider<MovieFinder> movieFinder) { 10 this.movieFinder = movieFinder; 11 } 12 13 public void listMovies() { 14 this.movieFinder.get().findMovies(...); 15 // ... 16 } 17}
1import jakarta.inject.Inject 2import jakarta.inject.Provider 3 4class SimpleMovieLister { 5 6 @Inject 7 lateinit var movieFinder: Provider<MovieFinder> 8 9 fun listMovies() { 10 movieFinder.get().findMovies(...) 11 // ... 12 } 13}
주입되어야 할 의존성에 대해 한정 이름을 사용하고 싶다면,
다음 예제에서 보듯이 @Named 어노테이션을 사용해야 합니다:
1import jakarta.inject.Inject; 2import jakarta.inject.Named; 3 4public class SimpleMovieLister { 5 6 private MovieFinder movieFinder; 7 8 @Inject 9 public void setMovieFinder(@Named("main") MovieFinder movieFinder) { 10 this.movieFinder = movieFinder; 11 } 12 13 // ... 14}
1import jakarta.inject.Inject 2import jakarta.inject.Named 3 4class SimpleMovieLister { 5 6 private lateinit var movieFinder: MovieFinder 7 8 @Inject 9 fun setMovieFinder(@Named("main") movieFinder: MovieFinder) { 10 this.movieFinder = movieFinder 11 } 12 13 // ... 14}
@Autowired와 마찬가지로, @Inject는 java.util.Optional 또는
@Nullable과 함께 사용할 수도 있습니다. 특히 여기서는 @Inject에
required 속성이 없기 때문에 더 잘 적용됩니다.
다음 예제 쌍은 @Inject와
@Nullable을 사용하는 방법을 보여줍니다:
1public class SimpleMovieLister { 2 3 @Inject 4 public void setMovieFinder(Optional<MovieFinder> movieFinder) { 5 // ... 6 } 7}
1public class SimpleMovieLister { 2 3 @Inject 4 public void setMovieFinder(@Nullable MovieFinder movieFinder) { 5 // ... 6 } 7}
1class SimpleMovieLister { 2 3 @Inject 4 var movieFinder: MovieFinder? = null 5}
@Named와 @ManagedBean: @Component 어노테이션의 표준 동등 요소@Component 대신에, 다음 예제에서 보듯이 @jakarta.inject.Named 또는 jakarta.annotation.ManagedBean을
사용할 수 있습니다:
1import jakarta.inject.Inject; 2import jakarta.inject.Named; 3 4@Named("movieListener") // @ManagedBean("movieListener") could be used as well 5public class SimpleMovieLister { 6 7 private MovieFinder movieFinder; 8 9 @Inject 10 public void setMovieFinder(MovieFinder movieFinder) { 11 this.movieFinder = movieFinder; 12 } 13 14 // ... 15}
1import jakarta.inject.Inject 2import jakarta.inject.Named 3 4@Named("movieListener") // @ManagedBean("movieListener") could be used as well 5class SimpleMovieLister { 6 7 @Inject 8 lateinit var movieFinder: MovieFinder 9 10 // ... 11}
@Component를 사용할 때 컴포넌트에 대한 이름을 지정하지 않는 것이 매우 일반적입니다.
다음 예제에서 보듯이, @Named도 비슷한 방식으로 사용할 수 있습니다:
1import jakarta.inject.Inject; 2import jakarta.inject.Named; 3 4@Named 5public class SimpleMovieLister { 6 7 private MovieFinder movieFinder; 8 9 @Inject 10 public void setMovieFinder(MovieFinder movieFinder) { 11 this.movieFinder = movieFinder; 12 } 13 14 // ... 15}
1import jakarta.inject.Inject 2import jakarta.inject.Named 3 4@Named 5class SimpleMovieLister { 6 7 @Inject 8 lateinit var movieFinder: MovieFinder 9 10 // ... 11}
@Named 또는 @ManagedBean을 사용할 때,
다음 예제에서 보듯이 Spring 어노테이션을 사용할 때와 정확히 동일한 방식으로
컴포넌트 스캐닝을 사용할 수 있습니다:
1@Configuration 2@ComponentScan(basePackages = "org.example") 3public class AppConfig { 4 // ... 5}
1@Configuration 2@ComponentScan(basePackages = ["org.example"]) 3class AppConfig { 4 // ... 5}
@Component와는 대조적으로, JSR-330@Named와 JSR-250@ManagedBean어노테이션은 합성 가능하지 않습니다. 커스텀 컴포넌트 어노테이션을 만들기 위해서는 Spring의 스테레오타입 모델을 사용해야 합니다.
표준 어노테이션으로 작업할 때, 다음 표에서 보듯이 몇 가지 중요한 기능이 제공되지 않는다는 점을 알아야 합니다:
| Spring | jakarta.inject.* | jakarta.inject 제한 사항 / 설명 |
|---|---|---|
| @Autowired | @Inject | @Inject에는 'required' 속성이 없습니다. 대신 Java 8의 Optional과 함께 사용할 수 있습니다. |
| @Component | @Named / @ManagedBean | JSR-330은 합성 가능한 모델을 제공하지 않고, 이름이 있는 컴포넌트를 식별하는 방법만 제공합니다. |
| @Scope("singleton") | @Singleton | JSR-330 기본 스코프는 Spring의 prototype과 유사합니다. 그러나 Spring의 일반적인 기본값과의 일관성을 유지하기 위해, Spring 컨테이너에 선언된 JSR-330 빈은 기본적으로 singleton입니다. singleton 이외의 스코프를 사용하려면, Spring의 @Scope 어노테이션을 사용해야 합니다. jakarta.inject는 또한 jakarta.inject.Scope 어노테이션을 제공합니다. 그러나 이것은 커스텀 어노테이션을 만들기 위한 용도로만 사용됩니다. |
| @Qualifier | @Qualifier / @Named | jakarta.inject.Qualifier는 커스텀 한정자를 만들기 위한 메타 어노테이션일 뿐입니다. 구체적인 String 한정자(값을 가진 Spring의 @Qualifier와 같은)는 jakarta.inject.Named를 통해 연결될 수 있습니다. |
| @Value | - | 동등한 기능 없음 |
| @Lazy | - | 동등한 기능 없음 |
| ObjectFactory | Provider | jakarta.inject.Provider는 Spring의 ObjectFactory에 대한 직접적인 대안으로, 단지 더 짧은 get() 메서드 이름을 가질 뿐입니다. 이는 Spring의 @Autowired와 조합하거나, 어노테이션이 없는 생성자 및 세터 메서드와 함께 사용할 수도 있습니다. |
Table 1. Spring 컴포넌트 모델 요소와 JSR-330 변형 비교
Classpath Scanning and Managed Components
Java-based Container Configuration