Spring을 사용하여 응용 프로그램을 개발 중입니다. @Service
주석 을 사용해야합니다 . 나는이 ServiceI
와 ServiceImpl
같은 그 ServiceImpl implements ServiceI
. @Service
주석 을 어디에 보관 해야하는지 혼란 스럽습니다 .
인터페이스 또는 구현에 주석을 달아야 @Service
합니까? 이 두 방법의 차이점은 무엇입니까?
답변
인터페이스에 쓸모가 없기 때문에 @Component
(또는 @Service
…) 인터페이스에 넣지 마십시오 . 이유를 설명하겠습니다.
주장 1 : 인터페이스가있는 경우 주 입점 유형에 해당 인터페이스를 사용하려고합니다.
주장 2 : 인터페이스의 목적은 여러 구현으로 구현 될 수있는 계약을 정의하는 것입니다. 다른쪽에는 주입 지점이 있습니다 ( @Autowired
). 인터페이스를 하나만 구현하고 클래스를 구현하는 클래스는 (IMHO) 쓸모 없으며 YAGNI를 위반 합니다 .
사실 : 당신이 넣을 때 :
@Component
@Service
인터페이스에서 (또는 …)- 그것을 구현하는 여러 클래스가 있습니다.
- 최소한 두 개의 클래스가 Spring Beans가되고
- 유형 기반 주입에 인터페이스를 사용하는 주입 지점이 있고
그리고 당신은 얻을 것이다 NoUniqueBeanDefinitionException
(또는 당신은 환경, 프로파일 또는 한정자 …와 매우 특별한 구성 설정이 …)
결론 : 당신이 사용하는 경우 @Component
(또는 @Service
인터페이스에, …) 다음 두 clains 중 적어도 하나를 위반해야합니다. 따라서 @Component
인터페이스 수준에서 사용하는 것은 유용하지 않다고 생각합니다 (일부 드문 경우 제외) .
Spring-Data-JPA 리포지토리 인터페이스는 완전히 다른 것입니다.
답변
@Service , @Repository , @Component 등의 기본 주석은 모두 동일한 목적을 제공합니다.
주석 기반 구성 및 클래스 경로 스캔 사용시 자동 감지
내 경험에서 나는 항상 사용하고 @Service
인터페이스 또는 같은 추상 클래스와 주석에 주석을 @Component
하고 @Repository
자신의 구현. @Component
주석 나는 기본 목적, 간단한 스프링 빈을 제공하는 클래스에서 사용하고 있습니다. 예를 들어 데이터베이스와 통신해야하거나 트랜잭션이있는 경우 등 레이어 @Repository
에서 사용중인 주석DAO
따라서 @Service
기능에 따라 인터페이스 및 기타 레이어로 인터페이스에 주석을 달 것을 제안 합니다.
답변
내가 사용 @Component
, @Service
, @Controller
및 @Repository
단지 구현 클래스에 아닌 인터페이스에 주석을. 그러나 @Autowired
인터페이스가있는 주석은 여전히 나에게 효과적이었습니다.
답변
@Service에 주석을 달면 장점은 그것이 서비스라는 힌트를 준다는 것입니다. 구현 클래스가 기본적 으로이 주석을 상속하는지 여부는 알 수 없습니다.
단점은 스프링 특정 주석을 사용하여 인터페이스를 특정 프레임 워크, 즉 Spring과 연결한다는 것입니다. 인터페이스가 구현에서 분리되어야하므로 프레임 워크 별 주석 또는 인터페이스의 객체 부분을 사용하지 않는 것이 좋습니다.
답변
스프링의 한 가지 장점은 서비스 (또는 다른) 구현을 쉽게 전환하는 것입니다. 이를 위해 인터페이스에 주석을 달고 다음과 같이 변수를 선언해야합니다.
@Autowired
private MyInterface myVariable;
아니 :
@Autowired
private MyClassImplementationWhichImplementsMyInterface myVariable;
첫 번째 경우와 같이 고유 한 순간부터 주입 할 구현을 활성화 할 수 있습니다 (한 클래스 만 인터페이스를 구현 함). 두 번째 경우에는 모든 코드를 리팩터링해야합니다 (새 클래스 구현에는 다른 이름이 있음). 결과적으로 주석은 인터페이스에 최대한 많이 있어야합니다. 또한 JDK 프록시는 이에 적합합니다. CGlib 프록시와 달리 런타임 유형이 미리 알려져 있기 때문에 응용 프로그램 시작시 생성되고 인스턴스화됩니다.
답변
나는 @Service
당신의 클래스에 넣을 것이지만 인터페이스의 이름을 주석에 대한 매개 변수로 넣습니다.
interface ServiceOne {}
@Service("ServiceOne")
class ServiceOneImpl implements ServiceOne{}
그렇게하면 모든 이점을 얻을 수 있으며 여전히 인터페이스를 주입 할 수 있지만 수업을받을 수 있습니다
@Autowired
private ServiceOne serviceOne;
따라서 인터페이스가 스프링 프레임 워크에 연결되어 있지 않으므로 언제든지 클래스를 변경할 수 있으며 모든 주입 지점을 업데이트 할 필요는 없습니다.
따라서 구현 클래스를 변경하려면 새 클래스에 주석을 달고 첫 번째 클래스에서 제거 할 수는 있지만 변경 해야하는 전부입니다. 클래스를 주입하면 impl 클래스를 변경하려고 할 때 많은 작업을 수행 할 수 있습니다.
답변
간단히 말해 :
@Service 는 서비스 계층에 대한 스테레오 타입 주석입니다 .
@Repository는 위한 스테레오 주석 인 지속성 층.
@Component 는 Spring에게 Application Context에서 객체의 인스턴스를 생성하도록 지시하는 데 사용되는 일반적인 고정 관념 주석입니다. 인스턴스의 이름을 정의 할 수 있습니다. 기본값은 낙타의 경우 클래스 이름입니다.