복붙노트

[SPRING] 추상 클래스에서 작동하지 않는 Spring 자동 와이어 링

SPRING

추상 클래스에서 작동하지 않는 Spring 자동 와이어 링

나는 인터페이스가있는 프로젝트, 같은 인터페이스를 구현하는 Abstract 클래스, 그리고이 인터페이스를 구현하고 추상 클래스를 확장하는 구체적인 클래스 세트를 가지고있다.

public interface Invoice
{
   void process();
}

@component
public abstract class AbstractInvoice(){

    @Resource
    protected Writer writer;

    protected validateInvoice(){
        //some implementation
    }
}

@Component
public Class TypeAInvoice() extends AbstractInvoice implements Invoice{

    @Override
    public void process(){
        //... some code
        writer.write();
    }
}

public Interface Writer(){
    public void write();
}

@Component
public class CDWriter implements Writer{
    @Override 
    public void write() { /* implementation.....*/}
}

Spring 파일에는 패키지에 대한 구성 요소 검사가 있습니다.

<context:annotation-config>
<context:component-scan base-package="com.xyz" />

팩토리를 사용하여 TypeAInvoice 송장 인스턴스를 가져옵니다. 이제 invoice.process ()를 호출하면 write.write ()로 갈 때 NPE를 얻습니다.

내가 뭘 놓치고 있는지 모르겠다. 구성 요소 스캔 및 범위를 보려고 시도했지만 개념적으로 잘못된 것을 찾을 수 없었습니다.

해결법

  1. ==============================

    1.공장에서하는 일에 따라 문제가 될 수 있습니다. 공장에서 새로운 TypeAInvoice를 생성하는 경우 스프링 배선이 적용되지 않습니다. Bean에 대한 Spring 컨텍스트를 쿼리해야한다. 한 가지 방법은 ContextLoader를 사용하는 것입니다.

    공장에서하는 일에 따라 문제가 될 수 있습니다. 공장에서 새로운 TypeAInvoice를 생성하는 경우 스프링 배선이 적용되지 않습니다. Bean에 대한 Spring 컨텍스트를 쿼리해야한다. 한 가지 방법은 ContextLoader를 사용하는 것입니다.

    return ContextLoader.getCurrentWebApplicationContext().getBean(TypeAInvoice.class)
    

    저는 정적 팩토리와 스프링이 잘 어울리지 않는다고 말하고 싶습니다. Spring은 Inversion of Control 패턴을 나타내며, Factories는 Service Locator 패턴을 나타냅니다. 나는 당신이 공장을 없애고 봄 콩을 autowire하는 것이 좋습니다거야.

  2. ==============================

    2.TypeAInvoice를 얻기 위해 팩토리를 사용한다는 사실을 제외하면 모든 것이 훌륭합니다. TypeAInvoice typer = new TypeAInvoice ()와 같이 작성하면 스프링이 아무것도 인식하지 못하고 Writer가 자동으로 실행되지 않으므로 NullPointerException이 발생합니다. 스프링 애플리케이션 컨텍스트에서 빈을 얻어야한다.

    TypeAInvoice를 얻기 위해 팩토리를 사용한다는 사실을 제외하면 모든 것이 훌륭합니다. TypeAInvoice typer = new TypeAInvoice ()와 같이 작성하면 스프링이 아무것도 인식하지 못하고 Writer가 자동으로 실행되지 않으므로 NullPointerException이 발생합니다. 스프링 애플리케이션 컨텍스트에서 빈을 얻어야한다.

  3. ==============================

    3.제 경우에는 스프링 4 애플리케이션에서 고전적인 추상 팩터 리 패턴 (http://java-design-patterns.com/patterns/abstract-factory/에서 아이디어를 가져 와서 각각 인스턴스를 생성해야만했습니다)을 사용해야했습니다. 그리고 때마다 작업이 완료되었습니다. 그래서 내 코드는 다음과 같이 설계되었습니다.

    제 경우에는 스프링 4 애플리케이션에서 고전적인 추상 팩터 리 패턴 (http://java-design-patterns.com/patterns/abstract-factory/에서 아이디어를 가져 와서 각각 인스턴스를 생성해야만했습니다)을 사용해야했습니다. 그리고 때마다 작업이 완료되었습니다. 그래서 내 코드는 다음과 같이 설계되었습니다.

    public abstract class EO {
        @Autowired
        protected SmsNotificationService smsNotificationService;
        @Autowired
        protected SendEmailService sendEmailService;
        ...
        protected abstract void executeOperation(GenericMessage gMessage);
    }
    
    public final class OperationsExecutor {
        public enum OperationsType {
            ENROLL, CAMPAIGN
        }
    
        private OperationsExecutor() {
        }
    
        public static Object delegateOperation(OperationsType type, Object obj) 
        {
            switch(type) {
                case ENROLL:
                    if (obj == null) {
                        return new EnrollOperation();
                    }
                    return EnrollOperation.validateRequestParams(obj);
                case CAMPAIGN:
                    if (obj == null) {
                        return new CampaignOperation();
                    }
                    return CampaignOperation.validateRequestParams(obj);
                default:
                    throw new IllegalArgumentException("OperationsType not supported.");
            }
        }
    }
    
    @Configurable(dependencyCheck = true)
    public class CampaignOperation extends EO {
        @Override
        public void executeOperation(GenericMessage genericMessage) {
            LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
        }
    }
    

    처음에는 추상 클래스에 종속성을 주입하기 위해 @Component, @Service 등의 모든 스테레오 타입 주석을 시도했지만 스프링 컨텍스트 파일에는 전체 패키지에 대해 ComponentScanning이 있었지만 CampaignOperation과 같은 하위 클래스 인스턴스를 생성하는 동안 Super Abstract 클래스 EO는 Spring이 그 의존성을 인식하고 삽입 할 수 없기 때문에 그 속성을 null로 가지는 것은 많은 시행 착오 끝에 ** Configurable (dependencyCheck = true) ** annotation을 사용했고 결국 Spring은 의존성을 주입 할 수 있었고 속성을 너무 많이 사용하지 않고 하위 클래스의 속성을 사용하십시오.

    <context:annotation-config />
    <context:component-scan base-package="com.xyz" />
    

    또한 해결책을 찾기 위해 다음 참조를 시도했습니다.

    ** @ Configurable (dependencyCheck = true) **을 사용해 보시고이 게시물을 업데이트하십시오. 문제가 발생할 경우 도와 드리겠습니다.

    그래서 정확하게 여기 내 요점은 당신이 항상 스프링 컨텍스트에서 콩을 얻을 필요가 없다는 것입니다.

  4. from https://stackoverflow.com/questions/11273070/spring-autowiring-not-working-for-abstract-classes by cc-by-sa and MIT license