JavaでMixin
mixiの日記で以前に同じようなことを書いたんだけど
http://d.hatena.ne.jp/brazil/20051001/1128099513
http://d.hatena.ne.jp/winebarrel/20051001#p6
を読んで自分がcglibで試したことをこっちにも書いてみることにする。
もしこれができれば実装の継承を
ある程度動的に組み込めるようになると思うんだけど
誰か良い手を知りませんか?
public interface Car {
public void run();
}
public interface Seat {
public void addSeat(Passenger pas);
}
public interface Bus extends Car, Seat {
}
public class BusSeatImpl implements Seat {private List list = new LinkedList();
public void addSeat(Passenger passenger) {
if (list.size() > 40) {
throw new RuntimeException("定員オーバーです");
}
list.add(passenger);
}
}
public class CarImpl implements Car {
public void run() {
System.out.println("Boo Boo!");
}
}
public class Passenger {
private String name;
}
public final class BusFactory {
public static Bus create() {
return (Bus) MixinFactory.create(Bus.class, new Object[] {new CarImpl(), new BusSeatImpl() });
}
}
public final class MixinFactory {public static Object create(Class returnIface, Object[] mixObjects) {
Object obj = Mixin.create(mixObjects);
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass());
enhancer.setInterfaces(new Class[] { returnIface });
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method arg1, Object[] args,MethodProxy proxy) throws Throwable {
return proxy.invokeSuper(obj, args);
}
});
return enhancer.create();
}
}
・・・
public void testCreate() {
Bus bus = BusFactory.create();
bus.addSeat(new Passenger());
bus.run();
}
素直にjavassistとか使ってmixinするフレームワークを作った方が良いかな?
java.lang.NullPointerException
at com.wikihouse.wildcats0201.test.cglib.Seat$$MixinByCGLIB$$99ebebff.addSeat()
at com.wikihouse.wildcats0201.test.cglib.Seat$$MixinByCGLIB$$99ebebff$$EnhancerByCGLIB$$5ae6db92.CGLIB$addSeat$0()
at com.wikihouse.wildcats0201.test.cglib.Seat$$MixinByCGLIB$$99ebebff$$EnhancerByCGLIB$$5ae6db92$$FastClassByCGLIB$$c1ed6462.invoke()
at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:167)