program tip

@Service 주석은 어디에 보관해야합니까?

radiobox 2020. 8. 12. 08:07
반응형

@Service 주석은 어디에 보관해야합니까? 인터페이스 또는 구현?


Spring을 사용하여 애플리케이션을 개발 중입니다. @Service주석 을 사용해야합니다 . 나는 그 ServiceIServiceImpl같은 ServiceImpl implements ServiceI. 여기서 @Service주석 을 어디에 보관해야하는지 혼란 스럽습니다 .

인터페이스 또는 구현에 주석을 추가해야합니까 @Service? 이 두 접근 방식의 차이점은 무엇입니까?


내가 넣어 결코 @Component(또는 @Service이 인터페이스가 쓸모하기 때문에, 인터페이스에, ...). 이유를 설명하겠습니다.

클레임 1 : 인터페이스가있는 경우 해당 인터페이스를 주입 지점 유형에 사용하려고합니다.

주장 2 : 인터페이스의 목적은 여러 구현에 의해 구현 될 수있는 계약을 정의하는 것입니다. 다른쪽에는 주입 지점 ( @Autowired)이 있습니다. 인터페이스가 하나만 있고이를 구현하는 클래스가 하나만있는 것은 (IMHO) 쓸모없고 YAGNI 위반 입니다.

사실 : 다음을 입력 할 때 :

  • @Component(또는 @Service, ...) 인터페이스에서
  • 이를 구현하는 여러 클래스가 있습니다.
  • 최소한 두 개의 클래스가 Spring Bean이되고
  • 유형 기반 주입에 인터페이스를 사용하는 주입 지점이 있습니다.

그런 다음 및 NoUniqueBeanDefinitionException(또는 환경, 프로필 또는 한정자와 함께 매우 특별한 구성 설정이 있습니다 ...)

결론 : 당신이 사용하는 경우 @Component(또는 @Service인터페이스에, ...) 다음 두 clains 중 적어도 하나를 위반해야합니다. 따라서 @Component인터페이스 수준 에 두는 것이 유용하지 않다고 생각합니다 (일부 드문 시나리오 제외) .


Spring-Data-JPA Repository 인터페이스는 완전히 다른 것입니다.


기본적으로 @Service , @Repository , @Component 등과 같은 주석은 모두 동일한 목적을 제공합니다.

주석 기반 구성 및 클래스 경로 스캔을 사용할 때 자동 감지.

내 경험상 나는 항상 @Service인터페이스 또는 추상 클래스 및 구현 @Component같은 주석에 주석 @Repository을 사용하고 있습니다. @Component기본 목적, 간단한 Spring Bean 등을 제공하는 클래스에서 사용하고 있습니다. 예를 들어 데이터베이스와 통신해야하는 경우, 일부 트랜잭션이있는 경우 @Repository와 같이 DAO계층 에서 사용중인 주석입니다 .

따라서 @Service기능에 따라 및 기타 레이어로 인터페이스에 주석을 달 것을 제안 합니다.


인터페이스가 아니라 구현 클래스에서만 @Component, @Service, @Controller 및 @Repository 주석을 사용했습니다. 그러나 인터페이스가있는 @Autowired 주석은 여전히 ​​나에게 효과적이었습니다.


@Service에 주석을 추가하는 장점은 그것이 서비스라는 힌트를 제공한다는 것입니다. 구현 클래스가 기본적으로이 주석을 상속하는지 여부는 알 수 없습니다.

단점은 스프링 특정 어노테이션을 사용하여 인터페이스를 특정 프레임 워크, 즉 Spring과 결합한다는 것입니다. 인터페이스는 구현에서 분리되어야하므로 프레임 워크 별 주석이나 인터페이스의 개체 부분을 사용하는 것이 좋습니다.


Spring의 한 가지 이점은 서비스 (또는 기타) 구현을 쉽게 전환 할 수 있다는 것입니다. 이를 위해 인터페이스에 주석을 달고 다음과 같이 변수를 선언해야합니다.

@Autowired
private MyInterface myVariable;

그리고 아닙니다 :

@Autowired
private MyClassImplementationWhichImplementsMyInterface myVariable;

첫 번째 경우와 같이 고유 한 순간부터 삽입 할 구현을 활성화 할 수 있습니다 (하나의 클래스 만 인터페이스를 구현 함). 두 번째 경우에는 모든 코드를 리팩터링해야합니다 (새 클래스 구현에는 다른 이름이 있음). 결과적으로 주석은 가능한 한 인터페이스에 있어야합니다. 또한 JDK 프록시는 이에 적합합니다. CGlib 프록시와 달리 런타임 유형이 미리 알려지기 때문에 애플리케이션 시작시 생성되고 인스턴스화됩니다.


간단히 말하면 :

@Service서비스 계층에 대한 스테레오 타입 주석입니다 .

@Repository는 위한 스테레오 주석 인 지속성 층.

@Component애플리케이션 컨텍스트에서 객체의 인스턴스를 생성하도록 Spring에 알리는 데 사용되는 일반적인 스테레오 타입 주석입니다. 인스턴스의 이름을 정의 할 수 있으며 기본값은 카멜 케이스로 된 클래스 이름입니다.


스프링 빈을 만드는 데 사용할 수있는 주석이 5 개 있습니다. 아래에 답변을 적으십시오.

인터페이스가 정말로 필요합니까? 각 서비스 인터페이스에 대해 하나의 구현을 가지려면 피하고 클래스 만 사용하십시오. 물론 RMI가 없거나 인터페이스 프록시가 필요한 경우.

@Repository-dao 레이어 클래스를 삽입하는 데 사용합니다.

@Service-서비스 계층 클래스를 삽입하는 데 사용합니다. 서비스 계층에서도 db 트랜잭션 관리를 위해 @Transactional 주석을 사용해야 할 수도 있습니다.

@Controller - use for your frontend layer controllers, such as JSF managed beans injecting as spring beans.

@RestController - use for spring rest controllers, this would help you to avoid every time to put @ResponseBody and @RequestBody annotations in your rest methods.

@Component - use it in any other case when you need to Inject spring bean which is not controller, service, or dao class

참고URL : https://stackoverflow.com/questions/16351780/where-should-service-annotation-be-kept-interface-or-implementation

반응형