[SPRING] 스프링 @Autowired 클래스의 새 인스턴스
SPRING스프링 @Autowired 클래스의 새 인스턴스
나는 봄에 익숙하지 않고 다음과 같은 상황에 처해있다.
저장소 클래스 :
@Repository
public class MyRepository {
// ...
}
저장소 클래스를 사용하는 클래스 :
public class MyClass extends AbstractClass {
@Autowired
private MyRepository myRepository;
//...
}
내 MyClass에 @Component 주석을 달고 @Autowired와 함께 사용하면 @Autowired MyRepository가 제대로 처리된다는 것을 알고 있습니다. 문제는 리플렉션을 통해 MyClass의 새 인스턴스를 만들어야하는 상황에 있습니다. 따라서 MyRepository는 해결되지 않으며 항상 null입니다.
이 상황에서 @Autowired를 사용할 수있는 방법이 있습니까?
더 나은 내 상황을 설명 : 나는 추상적 클래스의 구현을 가지고있다. 내 응용 프로그램의 설치 단계에서 이러한 구현의 HashMap을 만듭니다. 원래:
{"MyClass", MyClass.class}
//...
그런 다음 url / {class}? options =에 매핑되는 일반 컨트롤러가 있습니다. {class} @PathVariable, 위의 HashMap 및 리플렉션을 사용하여 주어진 옵션을 기반으로 클래스의 인스턴스를 만들 수 있습니다 (이 부분은 중요 함). 너 더 나은 방법이 있다고 생각하니?
미리 감사드립니다.
해결법
-
==============================
1.Spring 자체는 객체에서 자동 배선을 수행하는 몇 가지 기능을 제공합니다. new 또는 newInstance () 등으로 만든 클래스입니다.
Spring 자체는 객체에서 자동 배선을 수행하는 몇 가지 기능을 제공합니다. new 또는 newInstance () 등으로 만든 클래스입니다.
그것을 사용하려면 AutowireCapableBeanFactory가 필요합니다. @Autowired와 함께 Spring의 정상적인 의존성 주입으로 얻을 수있다.
@Autowired private AutowireCapableBeanFactory autowireCapableBeanFactory;
그런 다음 autowireBean (Object) 메소드를 사용합니다. @Autowired 속성을 빈에 삽입한다.
Object myBean = map.get(className).newInstance(); autowireCapableBeanFactory.autowireBean(myBean);
디자인 노트 :
위의 접근 방식이 정말로 필요하면 잘 생각하십시오. AutowireCapableBeanFactory의 javadoc은 대부분의 유스 케이스에서이 인터페이스를 사용하지 말 것을 권고합니다.
-
==============================
2.한 가지 해결 방법은 MyClass를 Hashmap에 바인딩하여 Factory 클래스를 바인딩하는 것이 아닙니다. MyClassFactory. 이렇게하면 올바른 클래스를 인스턴스화하고 올바른 저장소를 초기화하는 작업을 수행하는 구체적인 팩토리에 구성을 위임하게됩니다.
한 가지 해결 방법은 MyClass를 Hashmap에 바인딩하여 Factory 클래스를 바인딩하는 것이 아닙니다. MyClassFactory. 이렇게하면 올바른 클래스를 인스턴스화하고 올바른 저장소를 초기화하는 작업을 수행하는 구체적인 팩토리에 구성을 위임하게됩니다.
다음은 그 예입니다.
{"MyClass", MyClassFactory.class}
팩토리는 Component가 될 수 있습니다. 그러면 해시 맵을 팩토리 클래스 대신 팩토리 인스턴스에 바인딩해야합니다. 그러나 이것이 구성 요소가 아니라고 말할 수 있습니다.
//@Component this is optional public MyClassFactory { //@Autowired optional ApplicationContext ctx; public MyClass createInstance() { MyRepository repo = ctx.getBean("") MyClass myclass = new MyClass(repo) return myclass; } }
컴포넌트로 표시하면 ApplicationContext를 autowire 할 경우에도 ApplicationContextAware 인터페이스를 사용할 수 있습니다.
-
==============================
3.한 가지 방법은 @Component를 MyClass 위에 선언하는 것입니다.
한 가지 방법은 @Component를 MyClass 위에 선언하는 것입니다.
그런 다음 설치 단계에서 MyClass.class 자체 대신 MyClass의 인스턴스를 HashMap에 전달할 수 있습니다. 리플렉션을 통해 인스턴스를 만들 필요가 없습니다.
참고 : 설정 단계에서 ApplicationContext로부터 MyClass의 인스턴스를 가져올 수 있습니다.
-
==============================
4.이 시도
이 시도
@Component public class SomeClass extends AbstractClass { private static ApplicationContext applicationContext; public MyClass getMyClass(){ // Now @Autowired MyRepository will work return applicationContext.getBean(MyClass.class); } }
-
==============================
5.여기에 Factory Design Pattern을 사용할 수 있습니다.
여기에 Factory Design Pattern을 사용할 수 있습니다.
이것은 처음에는 조금 복잡해 보일지 모르지만, 구현 한 후에는 그것을 좋아할 것이라고 확신합니다.
단계 :
이 MyFactory 클래스의 Bean이 초기화되면, AbstractClass 타입의 모든 빈을 찾아서 HashMap (implementationMap)에 넣을 것이다.
이제이 팩토리에서 HashMap을 가져 와서 필요할 때 구현을 가져올 수 있습니다. 팩토리가 처리 할 때마다 AbstractClass의 새로운 구현을 추가하면 매우 쉽습니다.
-
==============================
6.예, 모든 AbstractClass 구현 빈에 @Component 주석을 달고 다음 선언을 사용할 수 있습니다.
예, 모든 AbstractClass 구현 빈에 @Component 주석을 달고 다음 선언을 사용할 수 있습니다.
@Autowired private List<AbstractClass> beans;
그런 다음이를 @PostConstruct 메소드의 Map으로 변환 할 수 있습니다.
List를 autowire하면 Spring은 중복 정의에 대해 불평하지 않을 것이다.
from https://stackoverflow.com/questions/52355132/spring-autowired-on-a-class-new-instance by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] CompletableFuture allof (..). join () vs CompletableFuture.join () (0) | 2019.06.20 |
---|---|
[SPRING] 스프링 MVC로 http 요청을 제대로 로깅하는 법 (0) | 2019.06.20 |
[SPRING] IntelliJ Idea 2017.3 Kotlin Spring Boot App을 시작할 수 없음 - @Configuration 클래스가 최종적이지 않을 수 있음 (0) | 2019.06.18 |
[SPRING] 도저를 스프링 부트와 함께 사용하는 방법? (0) | 2019.06.18 |
[SPRING] 스프링 : 스프링 보안 사용자에게 사용자 정의 세부 정보 추가 (0) | 2019.06.17 |