티스토리 뷰

ApplicationContext를 Util 클래스에서 가지고 와서 사용을 하고 싶었다. 그래서 다음과 같이 ApplicationContextAware를 impl하여 ApplicationContextProvider를 만들었다. 

@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    
    private static ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        applicationContext = ctx;
    }
    
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

ApplicationContextProvider.getApplicationContext()을 하면 어디서든 ApplicationContext를 가지고 올 수 있도록 만들었고 문제없이 잘 동작하였다. 

 

하지만! Sonarqube를 돌려보니 이건 위험한 코드니 고쳐야 한다고 한다. 

Make the enclosing method "static" or remove this set.

Correctly updating a static field from a non-static method is tricky to get right and could easily lead to bugs if there are multiple class instances and/or multiple threads in play. Ideally, static fields are only updated from synchronized static methods.

This rule raises an issue each time a static field is updated from a non-static method.

 

조금 찾아보니 위의 코드를 멋지게 리팩토링하신 분이 있었다. 

(http://daplus.net/java-spring-%ED%98%84%EC%9E%AC-applicationcontext-%EA%B0%80%EC%A0%B8-%EC%98%A4%EA%B8%B0/)

@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    
    private static class AplicationContextHolder {
        private static final InnerContextResource CONTEXT_PROV = new InnerContextResource();

        private AplicationContextHolder() {
            super();
        }
    }

    private static final class InnerContextResource {
        private ApplicationContext context;

        private InnerContextResource() {
            super();
        }

        private void setContext(ApplicationContext context) {
            this.context = context;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return AplicationContextHolder.CONTEXT_PROV.context;
    }

    @Override
    public void setApplicationContext(ApplicationContext ac) {
        AplicationContextHolder.CONTEXT_PROV.setContext(ac);
    }
}

ApplicationContextHolder라는 것을 만들고 그 안에 InnerContextResource에서 ApplicationContext를 set한다. 이렇게 캡슐화를 하는것은 어떻게 해야지 실력이 느는걸까... 대단하다. 

 

끝!

댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31