SingleTon 패턴을 우회해 인스턴스를 생성하는 방법.

2009. 10. 12. 09:00Java


SingleTon 패턴을 우회해 인스턴스를 생성할 수 있더군요.
Java 보안 모듈이 적용되지 않았다면, 인스턴스를 생성할 수 있네요.

보통 싱글톤 패턴을 아래와 같이 쓰실것입니다.

public class SingleTon {
 private static SingleTon st = null;
 
 private SingleTon(){
 
 }
 public SingleTon getInstance() {
  synchronized(SingleTon.class) { //Thread Safe
   if(st==null) st = new SingleTon();
   return st;
  }
 }
 
 public String toString() {
  return "SingleTon 생성됨";
 }
}

전혀 이상한것을 느끼지 못하시겠죠?
그러나 여기에도 구멍은 있더군요.
아래와 같이 한다면 이 클래스의 인스턴스를 생성할 수 있습니다.


public static void main(String[] args) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
  Class c = SingleTon.class;
  Constructor[] cons = c.getDeclaredConstructors();
 
  for(Constructor con:cons){
   System.out.println(con);
   con.setAccessible(true);
   
   SingleTon st = (SingleTon)con.newInstance(null);
   System.out.println(st);
  }
 }

결과:

private com.rontab.bake._net.test.robot.SingleTon()
SingleTon 생성됨


결과적으로 Reflection을 사용하면 위와같이 사용할수 있습니다.
근데 아직 이런 구멍을 어디에 사용할지 모르겠네요. 일반적인 상황이라면 쓸일이 없고,
정말 오래된 구 버전 코드를 사용한다거나, 테스트를 위해(?) 사용할지도 모르지요.

참고로, 저런 구멍까지 막으려면
인스턴스를 생성자 위에서 생성및 선언한후
생성자에 null 체크후 Exception을 던지면 됩니다.
예> if(st==null) {
            throw new Exception("싱글톤은 이걸 가지고 생성못한다.");
      }

참고:
http://yohanliyanage.blogspot.com/2009/09/breaking-singleton.html