sourcetip

추상 기본 클래스에서 @autowired 사용

fileupload 2023. 7. 22. 10:22
반응형

추상 기본 클래스에서 @autowired 사용

제가 아는 바로는field injection권장되지 않습니다.사용해야 함constructor대신.

여기서 제가 하려는 것은@Autowired기본 클래스의 생성자에서 모든 하위 클래스에 액세스할 수 있도록 합니다.일부 하위 클래스에서, 저는 또한 특정 콩이 필요합니다.@Autowired그들의 건설자로부터.데모 코드는 다음과 같습니다.

기본 클래스:

public abstract class Base {

    protected final MyDemoService myDemoService;

    @Autowired
    public Base(MyDemoService myDemoService) {
        this.myDemoService = myDemoService;
    }
}

상속된(하위) 클래스:

public class Sub extends Base {

    private final MySubService mySubService;

    @Autowired
    public Sub(MySubService mySubService) {
        this.mySubService = mySubService;
    }
} 

그러면 '기본 생성자 없음' 오류가 나타납니다.
질문과 비슷합니다. 질문과 대답은 비슷하지만 여기서는 작동하지 않습니다.


나는 한동안 이것에 대해 깊이 파고들었고, 나는 이 기사를 발견했습니다.dependency injection가독

내 생각엔..Setter Injection내 질문에 맞는 방법?

세터 주입:

public abstract class Base {

    protected MyDemoService myDemoService;

    @Autowired
    public void setMyDemoService(MyDemoService myDemoService) {
        this.myDemoService = myDemoService;
    }
}

저는 Java Spring Boot를 처음 사용하는 사람입니다. 여러분의 전문적인 조언을 듣고 싶습니다.어떤 토론이든 대단히 감사하겠습니다!

제공한 코드가 컴파일되지 않습니다.기본 클래스에 기본 생성자가 없는 한, 다음을 호출해야 합니다.super(MyDemoService)유아기에

상속된(하위) 클래스:

public class Sub extends Base {

    private final MySubService mySubService;

    @Autowired
    public Sub(MySubService mySubService, MyDemoService myDemoService){
        super(myDemoService);
        this.mySubService = mySubService;
    }
} 

아니면, 만약에MySubService의 구현입니다.MyDemoService

@Autowired
public Sub(MySubService mySubService){
    super(mySubService);
}

당신의 분야가 있는 한.MyDemoService myDemoService추상적인 수업에서는protected서브클래스에서 사용할 수 있습니다.

의 여러 구현이 있는 경우MyDemoService사용해야 하는 것보다@Qualifier당신이 언급한 답변에 기술된 바와 같이.

public Sub(@Qualifier("MySubService") MyDemoService mySubService){
    super(mySubService);
}

필드 주입을 사용하지 말고 슈퍼 생성자에 대한 생성자 주입 호출을 적절하게 사용합니다.

생성자 주입은 인스턴스화 전에 개체가 적절하게 채워지도록 하고, 세터 주입은 그렇지 않으며 코드를 더 버그 발생 가능성을 높입니다(다른 널 포인터 버그가 아님).

만약 당신이 추가로 작성해야 하는 코드가 걱정된다면, 여기에 설명된 것처럼 롬복 프로젝트를 사용하여 롬복이 당신을 위해 생성자 코드를 생성하도록 하십시오. 필드 주입이 나쁜 이유

그런데 봄 4일 현재 클래스에 생성자가 하나만 있는 경우 생성자에 @Autowired가 필요하지 않습니다.

를 사용하는 것이 좋습니다.@Configuration반.이렇게 하면 비즈니스 클래스에서 스프링 주석을 완전히 제거할 수 있습니다.

public class Sub extends Base {

    private final MySubService mySubService;

    public Sub(MySubService mySubService, MyDemoService myDemoService){
        super(myDemoService);
        this.mySubService = mySubService;
    }
} 

스프링 구성:

@Configuration
public class SubConfig{

    @Bean
    public Sub sub(MySubService subService, MyDemoService demoService){
        return new Sub(subService, demoService);
    }
}

Configuration 클래스를 사용하면 마법의 클래스 경로 검색에 더 이상 의존하지 않고 실제로 수동으로 빈을 다시 인스턴스화할 수 있습니다.이 접근 방식은 놀랄 일이 훨씬 적습니다.

효과가 있어요!!생성자 자동 배선 한정자 상속 주입

기본 추상 클래스 DocumentoBase입니다.

@Qualifier("DocumentServiceBase")
private DocumentService documentService;

@Autowired
public DocumentoBase(@Qualifier("DocumentServiceBase") DocumentService documentService){
    this.documentService = documentService;
}

DocumentoController 클래스를 상속했습니다.

@Qualifier("DocumentServiceImplv13")
private DocumentService documentService;

@Autowired
public DocumentoController(@Qualifier("DocumentServiceImplv13") DocumentService documentService){
    super(documentService);
    this.documentService = documentService;
}

주입으로는 할. 생성로주이할수를 . 기본 클래스 생성자의 종속성으로 하위 클래스 생성자를 확장하고 올바른 호출을 수행해야 합니다.super생성자(Spring을 사용하는 경우에도 표준 Java 규칙이 적용됩니다.

그러나 필드 및 세터 주입은 이를 올바르게 수행합니다.

코드 중복을 줄이기 때문에 어떠한 경우에도 필드 인젝션을 추천합니다.비교:

class A {
    @Autowired private Field field;
}

대.

class A {
    private final Field field;

    /** plus mandatory javadocs */
    @Autowired
    public A(Field field) {
        this.field = field;
    }
}

생성자 주입 예제에서는 원하는 방식으로 필드를 설정하기 위해 네 번 반복합니다.저는 최종적인 것을 좋아하지만, 이런 종류의 복제는 코드를 바꾸는 것을 어렵게 만듭니다.

언급URL : https://stackoverflow.com/questions/42713799/use-autowired-in-abstract-base-class

반응형