일반적으로 프로젝트에서 ValueObject객체를 만들어서 사용하게 되는데, 장점으로는 가벼운 객체
를 만들수있지만, 단점은 필드가 늘어나면 늘어날수록 getter/setter를 매번 만들어 주어야 하는
불편함이 있다.
아래 소스는 정의된 interface클래스 Sample만 사용해서 ValueObject형태로 만들어보는 예제 이다.
※ 테스트 하기 위해 만든 클래스
package com.shift.gef.xml;
public class SampleInstance {
public static void main(String[] args) {
// Sample sample = (Sample)InvokeHandler.getProxyInstance(com.shift.gef.xml.Sample.class);
/** 또는 아래와 같이 해도 된다 **/
Sample sample = (Sample)InvokeHandler.getProxyInstance("com.shift.gef.xml.Sample");
sample.setExpr("test");
sample.setSql("select * from dual");
System.out.println(sample.getExpr());
System.out.println(sample.getSql());
}
// Sample sample = (Sample)InvokeHandler.getProxyInstance(com.shift.gef.xml.Sample.class);
/** 또는 아래와 같이 해도 된다 **/
Sample sample = (Sample)InvokeHandler.getProxyInstance("com.shift.gef.xml.Sample");
sample.setExpr("test");
sample.setSql("select * from dual");
System.out.println(sample.getExpr());
System.out.println(sample.getSql());
}
}
※ 핵심이 되는 InvokeHandler 클래스
- InvokeHandler객체는 InvocationHandler인터페이스를 implements해서 작성하게 된다
- 아래 소스를 보면 알겠지만, invoke라는 메소드를 구현해 주어야 한다.
package com.shift.gef.xml;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
public class InvokeHandler implements InvocationHandler {
HashMap map = null;
private InvokeHandler() {
map = new HashMap();
}
/**
* 지정된 Interface클래스를 Proxy한 객체를 반환하는 메소드.
* @param className Class Name - String Type임.
* @return
*/
public static Object getProxyInstance(String className) {
try {
Class [] it = new Class[1] ;
it[0] = Class.forName(className);
return Proxy.newProxyInstance(InvokeHandler.class.getClassLoader(), it, new InvokeHandler());
} catch(ClassNotFoundException e) {
System.out.println(e.fillInStackTrace());
return null;
}
}
/**
* 지정된 Interface클래스를 Proxy한 객체를 반환하는 메소드.
* @param className Interface class
* @return
*/
public static Object getProxyInstance(Class cls) {
Class [] it = new Class[1] ;
it[0] = cls;
return Proxy.newProxyInstance(InvokeHandler.class.getClassLoader(), it, new InvokeHandler());
}
/**
* 지정된 Interface클래스를 Proxy한 객체를 반환하는 메소드.
* @param it Interface Class[]
* @return
*/
public static Object getProxyInstance(Class it[]) {
return Proxy.newProxyInstance(InvokeHandler.class.getClassLoader(), it, new InvokeHandler());
}
/**
* Interface의 내용중 Getter/Setter에 대한 Invoke처리.
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/** Setter Method Invoke **/
if (method.getName().indexOf("set") == 0) {
map.put(method.getName().substring(3), args[0]);
return null;
/** Getter Method Invoke **/
} else if (method.getName().indexOf("get") == 0) {
return map.get(method.getName().substring(3));
} else {
throw new NoSuchMethodException("입력하신 메소드 [" + method.getName() + "]를 처리할수가 없습니다.\n[Getter/Setter Method]만 사용 가능합니다.\n해당 Interface의 내용을 확인해 주세요!");
}
}
HashMap map = null;
private InvokeHandler() {
map = new HashMap();
}
/**
* 지정된 Interface클래스를 Proxy한 객체를 반환하는 메소드.
* @param className Class Name - String Type임.
* @return
*/
public static Object getProxyInstance(String className) {
try {
Class [] it = new Class[1] ;
it[0] = Class.forName(className);
return Proxy.newProxyInstance(InvokeHandler.class.getClassLoader(), it, new InvokeHandler());
} catch(ClassNotFoundException e) {
System.out.println(e.fillInStackTrace());
return null;
}
}
/**
* 지정된 Interface클래스를 Proxy한 객체를 반환하는 메소드.
* @param className Interface class
* @return
*/
public static Object getProxyInstance(Class cls) {
Class [] it = new Class[1] ;
it[0] = cls;
return Proxy.newProxyInstance(InvokeHandler.class.getClassLoader(), it, new InvokeHandler());
}
/**
* 지정된 Interface클래스를 Proxy한 객체를 반환하는 메소드.
* @param it Interface Class[]
* @return
*/
public static Object getProxyInstance(Class it[]) {
return Proxy.newProxyInstance(InvokeHandler.class.getClassLoader(), it, new InvokeHandler());
}
/**
* Interface의 내용중 Getter/Setter에 대한 Invoke처리.
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/** Setter Method Invoke **/
if (method.getName().indexOf("set") == 0) {
map.put(method.getName().substring(3), args[0]);
return null;
/** Getter Method Invoke **/
} else if (method.getName().indexOf("get") == 0) {
return map.get(method.getName().substring(3));
} else {
throw new NoSuchMethodException("입력하신 메소드 [" + method.getName() + "]를 처리할수가 없습니다.\n[Getter/Setter Method]만 사용 가능합니다.\n해당 Interface의 내용을 확인해 주세요!");
}
}
}
※ 예제에서 사용된 Sample인터페이스 클래스
package com.shift.gef.xml;
public interface Sample {
public String getExpr();
public void setExpr(String s);
public String getValue();
public void setValue(String s);
public String getType();
public void setType(String s);
public String getExpr();
public void setExpr(String s);
public String getValue();
public void setValue(String s);
public String getType();
public void setType(String s);
public String getSql();
public void setSql(String s);
}
public void setSql(String s);
}
인터페이스만 실제 예제를 돌려보면 인터페이스만 추가해 주면 일반적인 ValueObject객체와 같아
지는것을 볼수있다.
InvocationHandler를 어떤식으로 구현해서 응용하는냐에 따라 달려있음 ㅎㅎ
No comments:
Post a Comment