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