이게 필요한 경우가 생겼는데 난 당연히 안되겠지 하면서 ChatGPT에 물어보니 가르쳐줌;; 시발;;
다음 경우를 말한다.
@Component
class HolyShitHelper {
public String holyShit() {
return "Holy Moly...";
}
}
얘를 사용하고 싶은데 로직 상 리플렉션에 의해 생성된 객체 안에서는 Bean을 넣을 방법이… 없… 는 줄 알았는데 있다. 저 홀리쉿헬퍼를 사용하는 서비스가 다음과 같이 생겼다고 하면
class HolyShitService {
private HolyShitHelper holyShitHelper;
@Autowired
public void setHolyShitHelper(HolyShitHelper holyShitHelper) {
this.holyShitHelper = holyShitHelper;
}
public String serveHolyShit() {
return holyShitHelper.holyShit();
}
}
서비스레이어야 사실 @Service 어노테이션 써서 빈으로 만드는데 그냥 저런게 있다 치고, 저걸 다른 곳에서 리플렉션을 이용해서 인스턴스를 만들어서 사용하고 싶다고 합시다.
@Component
class HolyShitServer {
public String serveHolyShit() throws Exception {
var constructor = HolyShitService.class.getConstructor();
var service = constructor.newInstance();
return service.servceHolyShit();
}
}
HolyShitService는 Spring에서 관리하는 객체가 아니므로 @Autowired를 넣더라도 주입이 안된다. 그리고 빈이 아닌 곳에서 @Autowired를 쓰면 IDE에선 떽!!! 하면서 빨간줄을 그어주는데 사실 다음 소개할 방법으로 제대로 주입하면 실행은 된다. IDE 경고를 없애려면 일단 다음과 같이 경고를 무시할 수 있다.
@SuppressWarning("SpringJavaInjectionPointsAutowiringInspection")
class HolyShitService {
// 생략
}
그리고 HolyShitServer에서 다음 방법으로 하면 HolyShitHelper를 주입할 수 있다.
@Component
class HolyShitServer {
private ApplicationContext applicationContext;
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public String serveHolyShit() throws Exception {
var constructor = HolyShitService.class.getConstructor();
var service = constructor.newInstance();
var beanFactory = applicationContext.getAutowireCapableBeanFactory()
beanFactory.autowireBean(service);
return service.servceHolyShit();
}
}
로 하면 잘 된다.
참고로 코틀린으로도 잘 된다.
끗.
답글 남기기