SingleTon 패턴을 우회해 인스턴스를 생성하는 방법.
2009. 10. 12. 09:00ㆍJava
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 생성됨";
}
}
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 생성됨
SingleTon 생성됨
결과적으로 Reflection을 사용하면 위와같이 사용할수 있습니다.
근데 아직 이런 구멍을 어디에 사용할지 모르겠네요. 일반적인 상황이라면 쓸일이 없고,
정말 오래된 구 버전 코드를 사용한다거나, 테스트를 위해(?) 사용할지도 모르지요.
참고로, 저런 구멍까지 막으려면
인스턴스를 생성자 위에서 생성및 선언한후
생성자에 null 체크후 Exception을 던지면 됩니다.
예> if(st==null) {
throw new Exception("싱글톤은 이걸 가지고 생성못한다.");
}
참고:
http://yohanliyanage.blogspot.com/2009/09/breaking-singleton.html