[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.당신이 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.아니, 프로토 타입으로 범위가 지정된 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>
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
'SPRING' 카테고리의 다른 글
[SPRING] CSV 파일을 업로드하고 이에 따라 데이터베이스에 삽입하는 스프링 배치 (0) | 2019.03.24 |
---|---|
[SPRING] 스프링 보안에서 커스텀 인증 구현하기 (0) | 2019.03.24 |
[SPRING] 봄 OAuth2 TokenEndpoint에 대한 HTTP 기본 인증 사용 안 함 (0) | 2019.03.24 |
[SPRING] 왜 @Transactional 메서드가있는 클래스는 자동 실행되지 않을 수 있습니까? (0) | 2019.03.24 |
[SPRING] 스프링 캐시를위한 커스텀 KeyGenerator를 어떻게 설정합니까? (0) | 2019.03.24 |