@RefreshScope를 쓰지 않고 Monolithic에서 Bean update하기

ljk·2024년 4월 12일

이번 프로젝트를 진행하면서, 기존 프로젝트에서 불편하다고 느끼던 부분이였던 문구등의 간단한 수정으로 재배포 하는것을 방지하기 위해
ReloadableMessageResoure를 도입하였다.

근데 막상 ReloadableMessageResoure를 도입하니, 활용할 부분이 많은것 같았다.

일단 당장 프로젝트에서 도입할만한 부분은 custom한 WebClient bean이였다.

이 프로젝트에서는 Webclient를 활용한 scheduling이 있었는데,
schedule이 실행될 때 마다 동일한 설정의 WebClient를 활용하는건
불필요하다 생각하여 baseUrl과 header를 messages.properties에 작성한 후 WebClient를 bean으로 등록하였다.

문제는 bean으로 등록하다보니, ReloadableMessageSource 사용의 이점을 얻을 수가 없었다.

그래서 messages에서 내용을 수정하고 runtime에 bean update를 반영 할 수 있는 코드를 작성해보았다.

private final DefaultListableBeanFactory factory;

@PatchMapping("/{singleton}")
    public void tes(@PathVariable(name = "singleton") String singleton) {

        String higherDependency;

        try {
            higherDependency = factory.getDependenciesForBean(singleton)[0];
        } catch (ArrayIndexOutOfBoundsException e) {
            log.error(e.getStackTrace()[0].toString());
            throw new RuntimeException();
        }

        String[] lowerDependencies = factory.getDependentBeans(singleton);

        Object parentClass = factory.getBean(higherDependency);

        Object targetSingleton;

        try {
            targetSingleton = parentClass.getClass().getDeclaredMethod(singleton).invoke(parentClass);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            log.error(e.getStackTrace()[0].toString());
            throw new RuntimeException();
        }

        factory.destroySingleton(singleton);
        factory.registerSingleton(singleton, targetSingleton);

        factory.registerDependentBean(higherDependency, singleton);

        for (String dependency : lowerDependencies) {
            factory.registerDependentBean(singleton, dependency);
        }
    }

0개의 댓글