현장 주입이란 정확히 무엇이며, 이를 피하는 방법은 무엇입니까?
Spring MVC 및 Portlet에 대한 일부 게시물에서 필드 주입을 권장하지 않는다는 내용을 읽었습니다.제가 알기로는 현장주입이란 콩을 주사할 때@Autowired
음음음같 뭇매하다
@Component
public class MyComponent {
@Autowired
private Cart cart;
}
조사 중에 컨스트럭터 주입에 대해서도 읽었습니다.
@Component
public class MyComponent {
private final Cart cart;
@Autowired
public MyComponent(Cart cart){
this.cart = cart;
}
}
이 두 종류의 주사제의 장점과 단점은 무엇입니까?
편집 1: 이 질문은 이 질문의 중복으로 표시되어 있기 때문에 확인했습니다.질문에도 답변에도 코드 예시가 없기 때문에 어떤 주사 타입을 사용하고 있는지 정확하게 알 수 없습니다.
주입 타입
의존관계를 콩에 주입하는 방법에는 다음 3가지 옵션이 있습니다.
- 컨스트럭터 경유
- 설정기 또는 기타 방법을 통해
- 반영을 통해 직접 필드까지
3번입니다.이 기능을 사용하면 다음과 같은 현상이 발생합니다.@Autowired
현장에서 직접요.
주입 가이드라인
스프링에서 권장하는 일반적인 가이드라인(컨스트럭터 기반 DI 또는 세터 기반 DI 섹션 참조)은 다음과 같습니다.
- 필수 종속성 또는 불변성을 지향하는 경우 생성자 주입 사용
- 옵션 또는 변경 가능한 의존관계에 대해서는 setter injection을 사용합니다.
- 대부분의 경우 현장 주입을 피합니다.
필드 주입 단점
현장 주입이 눈살을 찌푸리게 되는 이유는 다음과 같습니다.
- 생성자 주입과 같이 불변 개체를 만들 수 없습니다.
- 클래스는 DI 컨테이너와 긴밀하게 결합되어 있어 외부에서 사용할 수 없습니다.
- 반영 없이 클래스를 인스턴스화할 수 없습니다(예: 단위 테스트).인스턴스화하려면 DI 컨테이너가 필요하므로 테스트가 통합 테스트와 비슷합니다.
- 실제 의존관계는 외부로부터 숨겨져 인터페이스(컨스트럭터 또는 메서드)에 반영되지 않습니다.
- 열 개 정도의 의존관계를 갖는 것은 정말 쉽다.생성자 주입을 사용하는 경우 10개의 인수가 있는 생성자가 있을 수 있으며, 이는 무언가 수상하다는 것을 나타냅니다.그러나 필드 주입을 사용하여 주입된 필드를 무한정 추가할 수 있습니다.의존관계가 너무 많으면 클래스가 보통 여러 가지 작업을 수행하고 단일 책임 원칙을 위반할 수 있다는 빨간색 플래그가 표시됩니다.
결론
필요에 따라 주로 생성자 주입을 사용하거나 생성자와 세터 주입을 혼합하여 사용해야 합니다.필드 주입에는 많은 단점이 있으므로 피해야 합니다.현장 주입의 유일한 장점은 쓰기가 더 편리하다는 것인데, 모든 단점을 능가하지는 않습니다.
추가 정보
현장 주입이 권장되지 않는 이유에 대한 블로그 기사를 작성했습니다.필드 의존성 주입은 유해한 것으로 간주됩니다.
이는 소프트웨어 개발의 끝없는 논의 중 하나이지만 업계의 주요 영향력 행사자들은 이 주제에 대해 더 많은 의견을 가지고 있으며 더 나은 옵션으로 컨스트럭터 주입을 제안하기 시작했습니다.
생성자 주입
장점:
- 테스트 용이성 향상.유닛 테스트에 조롱 라이브러리나 스프링 컨텍스트는 필요하지 않습니다.새 키워드를 사용하여 테스트할 개체를 만들 수 있습니다.이러한 테스트는 반사 메커니즘에 의존하지 않기 때문에 항상 더 빠릅니다.(이 질문은 30분 후에 행해졌습니다.작성자가 생성자 주입을 사용했다면 나타나지 않았을 것입니다.)
- 불변.일단 종속성이 설정되면 변경할 수 없습니다.
- 더 안전한 암호.생성자를 실행한 후 매개 변수로 전달된 모든 항목을 검증할 수 있으므로 개체를 사용할 수 있습니다.개체는 준비 상태이거나 준비되지 않은 상태일 수 있습니다.현장 주입에서는 물체가 깨지기 쉬운 중간 단계를 도입합니다.
- 필수 종속성을 보다 명확하게 표현합니다.이 문제에 있어서 현장 주입은 애매하다.
- 개발자가 설계에 대해 생각하게 합니다.dit은 8개의 매개변수를 가진 컨스트럭터에 대해 썼습니다.이것은 실제로 나쁜 설계와 신의 오브젝트 안티패턴의 징조입니다.클래스가 생성자에 8개의 종속성을 가지든 필드에 8개의 종속성을 가지든 상관없습니다.클래스는 항상 틀립니다.사람들은 필드를 경유하는 것보다 컨스트럭터에 더 많은 종속성을 추가하는 것을 더 꺼립니다.잠시 멈춰서 코드 구조를 생각해야 한다는 신호를 뇌에 보내는 역할을 합니다.
단점:
- 코드가 많을수록(그러나 최신 IDE는 문제를 완화합니다).
기본적으로 현장 주입은 반대입니다.
취향의 문제.그건 네 결정이야.
하지만 내가 왜 컨스트럭터 주입을 사용하지 않는지 설명할 수 있어.
컨스트럭터를 구현하고 싶지 않습니다.
@Service
,@Repository
그리고.@Controller
콩이 40~50개 정도 있어요.새 필드를 추가할 때마다 생성자를 확장해야 합니다.아니, 난 원하지도 않고 그럴 필요도 없어사용하시는 Bean(서비스 또는 컨트롤러)에서 다른 콩을 많이 주입해야 한다면 어떻게 하시겠습니까?파라미터가 4개 이상인 컨스트럭터는 매우 추악합니다.
CDI를 사용하는 경우 컨스트럭터는 상관없습니다.
편집 No.1: Vojtech Ruzicka는 다음과 같이 말합니다.
클래스는 의존관계가 너무 많아 단일 책임 원칙을 위반할 수 있으므로 리팩터링해야 합니다.
네, 이론과 현실이죠예를 들어 다음과 같습니다.DashboardController
단일 경로에 매핑*:8080/dashboard
.
나의DashboardController
는 다른 서비스로부터 많은 정보를 수집하여 대시보드/시스템 개요 페이지에 표시합니다.이 컨트롤러가 필요해요.따라서 이 1개의 패스(기본 인증 또는 사용자 역할 필터)만 보호해야 합니다.
편집 #2: 컨스트럭터의 8가지 파라미터에 모두가 집중되어 있기 때문에...이것은 실제 사례입니다.고객의 레거시 코드입니다.나는 그것을 바꿨다.4+ 파라미터에 대해서도 같은 인수가 적용됩니다.
인스턴스 구축이 아니라 코드 주입이 중요합니다.
또 한 가지 코멘트 - Vojtech Ruzicka는 Spring은 다음과 같은 세 가지 방법으로 콩을 주입한다고 말했다(가장 많은 점수를 받은 답변).
- 컨스트럭터 경유
- 설정기 또는 기타 방법을 통해
- 반영을 통해 직접 필드까지
이 답은 틀렸습니다. 왜냐하면 모든 종류의 주입 스프링은 반사를 사용하기 때문입니다! IDE를 사용하여 설정기/생성자에 중단점을 설정하고 확인합니다.
이것은 미각의 문제일 수도 있지만 케이스의 문제일 수도 있습니다.@dieter는 현장 주입이 더 좋을 때 훌륭한 케이스를 제공했습니다.스프링 콘텍스트를 설정하고 있는 통합 테스트에서 필드 주입을 사용하는 경우(클래스의 테스트 가능성과 함께 인수는 무효입니다).다만, 통합 테스트에 나중에 쓰는 경우는 제외합니다.)
언급URL : https://stackoverflow.com/questions/39890849/what-exactly-is-field-injection-and-how-to-avoid-it
'programing' 카테고리의 다른 글
Vue.js 동적 이미지 경로가 로드되지 않음 (0) | 2022.07.14 |
---|---|
gcc C 컴파일러는 C로 작성되어 있습니까? (0) | 2022.07.14 |
Vue SPA - 사용자가 인증되었는지 확인하고 인증되지 않은 경우 로그인으로 수정합니다. (0) | 2022.07.14 |
warning: 문자열 리터럴이 아닌 형식 인수 및 no format 인수 (0) | 2022.07.14 |
글로벌 변수와 스태틱 변수가 기본값으로 초기화되는 이유는 무엇입니까? (0) | 2022.07.14 |