복붙노트

[SPRING] 사실상 프로토 타입 인 autowired 필드의 새로운 인스턴스를 얻는보다 깔끔한 방법

SPRING

사실상 프로토 타입 인 autowired 필드의 새로운 인스턴스를 얻는보다 깔끔한 방법

나는이 문제에 직면했다. runnable 클래스를 autowire하고 다른 호출에서 다른 인스턴스를 생성하여 배열에 유지하려고 시도했다.

xml 구성은 다음과 같습니다.

<bean name="threadName" Class="ABC" scope="prototype" />

내 코드에서는 다음과 같은 것을 시도하고있다.

public class ThreadHandler{


@Autowired
private ABC threadName;

//getter
ABC getThreadName(){
     return threadName;
}

public void someFunction(){
     List<ABC> abc = new ArrayList(ABC>();
     for (int i=0;i<SOME_CONST;i++){
          ABC tName = getThreadName();
          abc.add(tName);
          tName.start();
      }
}   

}

ABC를 Thread / Runnable / Callable 인 클래스로합시다.

이 방법으로 java.lang.IllegalThreadStateException을 발생시킵니다. 하지만, ABC tName = appContext.getBean ( "threadName", ABC.class);

왜 그렇게됩니까?

getMethod에서 객체를 가져 오는 동안 새로운 인스턴스를 얻지 않습니까?

해결법

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

    1.당신이 Runnable / Callable을 생성하고 그것을 lookup 메소드라고 부르는 applicationContext에 삽입 할 필요가있을 때 훨씬 더 나은 실습이 있습니다 :

    당신이 Runnable / Callable을 생성하고 그것을 lookup 메소드라고 부르는 applicationContext에 삽입 할 필요가있을 때 훨씬 더 나은 실습이 있습니다 :

    Runnable / Callable 클래스는 @Prototype과 @Lazy라고 생각해 봅시다.

    @Component(value="task")
    @Scope(value="prototype")
    @Lazy(value=true)
    public class Task implements Runnable {
    
    public void run(){
    .....
    }
    
    }
    

    이제 Look up 메서드 팩토리를 생성해야합니다.

        <bean id="taskFactory" class="x.y.z.TaskFactory">
    <lookup-method name="createTask" bean="task"/>
    </bean>
    

    이제 추상 클래스 인 TaskFactory 자체를 구현하고 하나의 추상 메소드를 갖도록합시다.

    @Component(value="taskFactory")
    public abstract class TaskFactory {
    
        public abstract Task createTask();
    
    }
    

    여기 마술이옵니다 :

    public class ThreadHandler{
    
    @Autowired
    private TaskFactory taskFactory;
    
    
    public void someFunction(){
              Runnable task = taskFactory.createTask();
              taskExecutor.execute(task);
          }
    }   
    

    taskFactory 싱글 톤 객체의 createTask () 메소드를 호출 할 때마다. 프로토 타입 객체의 완전히 새로운 인스턴스를 받게됩니다.

    추신 : 잊지 마세요.

    <context:annotation-config />
        <context:component-scan base-package="x.y.z"></context:component-scan>
    

    특수 효과를 올바르게 사용합니다.

    도움이되기를 바랍니다.

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

    2.아니, 프로토 타입으로 범위가 지정된 bean에 대한 참조를 보유하는 필드에 액세스하는 것만으로 새로운 객체를 얻지 못합니다. Spring은 인스턴스 참조만을 필드 참조에 기반한 새로운 참조로 대체 할 방법이 없습니다. 자동 와이어 링 (autowiring)에 의해 한 번 설정되고 그 다음에는 하나의 객체에 대한 참조 일뿐입니다. 실제로 새 클래스를 작성하려면 getBean을 관찰 할 때 사용해야합니다.

    아니, 프로토 타입으로 범위가 지정된 bean에 대한 참조를 보유하는 필드에 액세스하는 것만으로 새로운 객체를 얻지 못합니다. Spring은 인스턴스 참조만을 필드 참조에 기반한 새로운 참조로 대체 할 방법이 없습니다. 자동 와이어 링 (autowiring)에 의해 한 번 설정되고 그 다음에는 하나의 객체에 대한 참조 일뿐입니다. 실제로 새 클래스를 작성하려면 getBean을 관찰 할 때 사용해야합니다.

    Spring에게 get 메소드를 오버라이드하고 메소드 인젝션을 사용하여 'getBean'으로 대체하여 Bean에서 Spring 의존성을 가져 오도록 Spring에 지시 할 수있다.

    <bean id="threadHandler" class="com.stackexchange.ThreadHandler">
    <lookup-method name="getThreadName" bean="threadName"/>
    </bean>
    
  3. from https://stackoverflow.com/questions/10358035/cleaner-way-to-get-new-instance-of-an-autowired-field-that-is-prototype-in-natur by cc-by-sa and MIT license