복붙노트

[SPRING] @Autowired와의 바인딩은 'new'로 시작된 인스턴스 안에서 작업하지 않습니다.

SPRING

@Autowired와의 바인딩은 'new'로 시작된 인스턴스 안에서 작업하지 않습니다.

웹 스프링 애플리케이션에서 다음과 같이 키워드 new를 사용하여 인스턴스를 만듭니다. 액션 클래스 중 하나에서 다음과 같은 메소드가 존재합니다.

public void process() { 

    MyBean b=new MyBean(); //initiated the instance with new  
    b.process();
}   

다른 MyBean 클래스

@Service
public class MyBean {  

@Autowired  
MyService service;  

public void process() { 
    service.execute(); // this service instance has not initialized by Spring DI :( .service object is null. 
}

MyService 인스턴스는 Spring 종속성 삽입으로 설정되지 않습니다. Spring이 아닌 MyBean의 인스턴스를 직접 생성하기 때문입니까?

해결법

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

    1.프로그래밍 방식으로 자동 와이어 링하려는 경우 다음을 사용할 수 있습니다.

    프로그래밍 방식으로 자동 와이어 링하려는 경우 다음을 사용할 수 있습니다.

    private @Autowired AutowireCapableBeanFactory beanFactory;
    
    public void process() {
       MyBean obj = new MyBean();
       beanFactory.autowireBean(obj);
       // obj will now have its dependencies autowired.
    }
    
  2. ==============================

    2.예. 새 키워드를 사용하여 생성 한 인스턴스가 Spring 컨테이너에 의해 관리되지 않으므로 Spring의 DI로 설정되지 않습니다. Spring은 기본적으로 스프링 관리 인스턴스에 대해서만 종속성을 주입합니다. 따라서이 문제를 해결하려면 두 가지 방법으로 해결할 수 있습니다. 첫 번째는 new를 사용하지 않고 @Autowired on Mybean 인스턴스를 사용합니다.

    예. 새 키워드를 사용하여 생성 한 인스턴스가 Spring 컨테이너에 의해 관리되지 않으므로 Spring의 DI로 설정되지 않습니다. Spring은 기본적으로 스프링 관리 인스턴스에 대해서만 종속성을 주입합니다. 따라서이 문제를 해결하려면 두 가지 방법으로 해결할 수 있습니다. 첫 번째는 new를 사용하지 않고 @Autowired on Mybean 인스턴스를 사용합니다.

    두 번째는 MyBean 클래스에서 @Configurable을 사용하는 것이다. @Configurable annotation spring은 new 키워드를 통해 생성 된 객체에 대해서도 의존성을 주입합니다. Dependecies를 삽입하기 위해서는 @configurable annotation으로 classpath에 AspectJ jar를 저장해야한다.

    두 번째 방법은 @Configurable (preConstruction = true)을 사용하고 pom.xml에 다음 종속성을 추가합니다.

    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>3.1.1.RELEASE</version>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.8</version>
    </dependency>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.6.8</version>
    </dependency>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjtools</artifactId>
    <version>1.6.8</version>
    </dependency>
    

    생성 된 바이트 코드가 필요한 능력을 갖도록 AspectJ Compiler를 통해 컴파일해야한다. 컴파일시 AspectJ 컴파일러를 사용하여 시스템을 확인하려면 다음 항목을 사용해야합니다.

    <build>
    <plugins>
    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.4</version>
    <configuration>
    <showWeaveInfo>true</showWeaveInfo>
    <source>1.6</source>
    <target>1.6</target>
    <Xlint>ignore</Xlint>
    <complianceLevel>1.6</complianceLevel>
    <encoding>UTF-8</encoding>
    <verbose>false</verbose>
    <aspectLibraries>
    <aspectLibrary>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    </aspectLibrary>
    </aspectLibraries>
    </configuration>
    <executions>
    <execution>
    <goals>
    <goal>compile</goal>
    <goal>test-compile</goal>
    </goals>
    </execution>
    </executions>
    <dependencies>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.6.8</version>
    </dependency>
    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjtools</artifactId>
    <version>1.6.11</version>
    </dependency>
    </dependencies>
    </plugin>
    </plugins>
    </build>
    
  3. ==============================

    3.new로 개체를 만들 때 autowire \ inject가 작동하지 않습니다 ...

    new로 개체를 만들 때 autowire \ inject가 작동하지 않습니다 ...

    이 문제를 해결할 수있는 해결 방법은 다음과 같습니다.

    MyBean의 템플릿 빈을 만든다.

    <bean id="myBean" class="..." scope="prototype">
        <!-- collaborators and configuration for this bean go here -->
    </bean>
    

    이 방법으로 인스턴스를 생성합니다.

    context.getBean("myBean");
    

    PROTOTYPE : 이것은 하나의 bean 정의가 여러개의 객체 인스턴스를 가지도록 범위를 지정한다.

  4. ==============================

    4.귀하의 경우 스프링은 MyBean 빈을 새로운 연산자로 생성하기 때문에 MyBean 빈을 인식하지 못합니다. Spring이이 빈을 초기화하도록하면, MyBean 내부에서 액세스되는 autowired 빈을 가질 수있다. 예 :

    귀하의 경우 스프링은 MyBean 빈을 새로운 연산자로 생성하기 때문에 MyBean 빈을 인식하지 못합니다. Spring이이 빈을 초기화하도록하면, MyBean 내부에서 액세스되는 autowired 빈을 가질 수있다. 예 :

    <bean id="myBean" class="your.package.MyBean"></bean>
    

    응용 프로그램 컨텍스트에서 위의 항목은 Spring 컨테이너에 MyBean을 생성합니다. 그리고이 객체를 사용하여 그 내부에 작성된 서비스에 액세스 할 수 있습니다.

  5. ==============================

    5.또 다른 해결책은 @Component를 다음과 같이 사용할 수 있습니다.

    또 다른 해결책은 @Component를 다음과 같이 사용할 수 있습니다.

    @Component("myBean")
    public class MyBean{  
    
        @Autowired  
        MyService service;  
    
        public void process(){ 
    
        service.execute(); // this service instance has not initialized by Spring DI :( .service object is null. 
    
        }
    }
    

    그리고 process ()가있는 클래스에서 다음과 같이 Autowire 할 수 있습니다 :

    @Autowired
    MyBean b
    
    public void process(){  
    
    
      b.process();
    
    
    }   
    
  6. from https://stackoverflow.com/questions/25635845/binding-with-autowired-not-working-inside-instances-initiated-with-new by cc-by-sa and MIT license