cglibを使って動的コード生成
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[JAVAの記事一覧]]
&topicpath;
*目次 [#bca26b28]
#contents
*CGLIBとは? [#fa0ae660]
CGLIBとは、Javaコード生成ライブラリです。クラスファイルを...
**CGLIBのWebページ [#xf7e883a]
http://cglib.sourceforge.net/
*本ページの趣旨 [#x0113801]
jparsecみてたら、動的ソースコード生成のライブラリであるcg...
興味が湧いたのでまとめてみる
ついでに、サンプルのコードの説明がなかったので、自分で説...
SpringやらHibernateなんかに内部的に使われているライブラリ...
*インタフェース定義するだけでPOJO的なインスタンスを生成す...
net.sf.cglib.core.KeyFactoryのすごいのは、なんといっても...
http://cglib.sourceforge.net/xref/samples/KeySample.html
package samples;
import net.sf.cglib.core.KeyFactory;
public class KeySample {
private interface MyFactory {
public Object newInstance(int a, char[] b, Str...
}
public static void main(String[] args) {
MyFactory f = (MyFactory)KeyFactory.create(MyF...
Object key1 = f.newInstance(20, new char[]{ 'a...
Object key2 = f.newInstance(20, new char[]{ 'a'...
Object key3 = f.newInstance(20, new char[]{ 'a'...
System.out.println(key1.equals(key2));
System.out.println(key2.equals(key3));
}
}
*実行トレーサを作るサンプル [#p0328206]
http://cglib.sourceforge.net/xref/samples/Trace.html
*解説 [#t66723cd]
Enhancer クラスの使い方のサンプル
クラスのインスタンスの作成をnew ではなく
汎用的に作られたnewInstanceメソッドで生成すると
なんと、そのインスタンスのメソッドを実行するたびに、
そのメソッドをインターセプトというかフックと言うべきか横...
どこの何のメソッドが実行されているのか、パラメータは何な...
**サンプル [#o73635e1]
package samples;
import net.sf.cglib.proxy.*;
import java.util.*;
/***
*
* @author baliuka
*/
public class Trace implements MethodInterceptor {
int ident = 1;
static Trace callback = new Trace();
/*** Creates a new instance of Trace */
private Trace() {
}
public static Object newInstance( Class clazz ){
try{
Enhancer e = new Enhancer();
e.setSuperclass(clazz);
e.setCallback(callback);
return e.create();
}catch( Throwable e ){
e.printStackTrace();
throw new Error(e.getMessage());
}
}
/***
* @param args the command line arguments
*/
public static void main(String[] args) {
List list = (List)newInstance(Vector.class);
Object value = "TEST";
list.add(value);
list.contains(value);
try{
list.set(2, "ArrayIndexOutOfBounds" );
}catch( ArrayIndexOutOfBoundsException ignore ){
}
list.add(value + "1");
list.add(value + "2");
list.toString();
list.equals(list);
list.set( 0, null );
list.toString();
list.add(list);
list.get(1);
list.toArray();
list.remove(list);
list.remove("");
list.containsAll(list);
list.lastIndexOf(value);
}
public Object intercept(Object obj, java.lang.refle...
MethodProxy proxy) throws T...
printIdent(ident);
System.out.println( method );
for( int i = 0; i < args.length; i++ ){
printIdent(ident);
System.out.print( "arg" + (i + 1) + ": ");
if( obj == args[i])
System.out.println("this");
else
System.out.println(args[i]);
}
ident++;
Object retValFromSuper = null;
try {
retValFromSuper = proxy.invokeSuper(obj, ar...
ident--;
} catch (Throwable t) {
ident--;
printIdent(ident);
System.out.println("throw " + t );
System.out.println();
throw t.fillInStackTrace();
}
printIdent(ident);
System.out.print("return " );
if( obj == retValFromSuper)
System.out.println("this");
else System.out.println(retValFromSuper);
if(ident == 1)
System.out.println();
return retValFromSuper;
}
void printIdent( int ident ){
while( --ident > 0 ){
System.out.print(".......");
}
System.out.print(" ");
}
}
**実行結果 [#j90f41b1]
mainメソッドの1行1行実行されるたびに、コンソールにメッ...
public synchronized boolean java.util.Vector.add(java....
arg1: TEST
return true
public boolean java.util.Vector.contains(java.lang.Obje...
arg1: TEST
....... public synchronized int java.util.Vector.indexO...
....... arg1: TEST
....... arg2: 0
....... return 0
return true
public synchronized java.lang.Object java.util.Vector.s...
arg1: 2
arg2: ArrayIndexOutOfBounds
throw java.lang.ArrayIndexOutOfBoundsException: Array i...
public synchronized boolean java.util.Vector.add(java.l...
arg1: TEST1
return true
public synchronized boolean java.util.Vector.add(java.l...
arg1: TEST2
return true
public synchronized java.lang.String java.util.Vector.t...
....... public java.util.Iterator java.util.AbstractLis...
....... return java.util.AbstractList$Itr@13b06041
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 0
....... return TEST
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 1
....... return TEST1
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 2
....... return TEST2
....... public synchronized int java.util.Vector.size()
....... return 3
return [TEST, TEST1, TEST2]
public synchronized boolean java.util.Vector.equals(jav...
arg1: this
return true
public synchronized java.lang.Object java.util.Vector.s...
arg1: 0
arg2: null
return TEST
public synchronized java.lang.String java.util.Vector.t...
....... public java.util.Iterator java.util.AbstractLis...
....... return java.util.AbstractList$Itr@1c701a27
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 0
....... return null
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 1
....... return TEST1
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 2
....... return TEST2
....... public synchronized int java.util.Vector.size()
....... return 3
return [null, TEST1, TEST2]
public synchronized boolean java.util.Vector.add(java.l...
arg1: this
return true
public synchronized java.lang.Object java.util.Vector.g...
arg1: 1
return TEST1
public synchronized java.lang.Object[] java.util.Vector...
return [Ljava.lang.Object;@ffdadcd
public boolean java.util.Vector.remove(java.lang.Object)
arg1: this
....... public synchronized boolean java.util.Vector.re...
....... arg1: this
.............. public int java.util.Vector.indexOf(java...
.............. arg1: this
..................... public synchronized int java.util...
..................... arg1: this
..................... arg2: 0
............................ public synchronized boolea...
............................ arg1: null
............................ return false
............................ public synchronized boolea...
............................ arg1: TEST1
............................ return false
............................ public synchronized boolea...
............................ arg1: TEST2
............................ return false
............................ public synchronized boolea...
............................ arg1: this
............................ return true
..................... return 3
.............. return 3
.............. public synchronized void java.util.Vecto...
.............. arg1: 3
.............. return null
....... return true
return true
public boolean java.util.Vector.remove(java.lang.Object)
arg1:
....... public synchronized boolean java.util.Vector.re...
....... arg1:
.............. public int java.util.Vector.indexOf(java...
.............. arg1:
..................... public synchronized int java.util...
..................... arg1:
..................... arg2: 0
..................... return -1
.............. return -1
....... return false
return false
public synchronized boolean java.util.Vector.containsAl...
arg1: this
....... public java.util.Iterator java.util.AbstractLis...
....... return java.util.AbstractList$Itr@50269997
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 0
....... return null
....... public boolean java.util.Vector.contains(java.l...
....... arg1: null
.............. public synchronized int java.util.Vector...
.............. arg1: null
.............. arg2: 0
.............. return 0
....... return true
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 1
....... return TEST1
....... public boolean java.util.Vector.contains(java.l...
....... arg1: TEST1
.............. public synchronized int java.util.Vector...
.............. arg1: TEST1
.............. arg2: 0
.............. return 1
....... return true
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 2
....... return TEST2
....... public boolean java.util.Vector.contains(java.l...
....... arg1: TEST2
.............. public synchronized int java.util.Vector...
.............. arg1: TEST2
.............. arg2: 0
.............. return 2
....... return true
....... public synchronized int java.util.Vector.size()
....... return 3
return true
public synchronized int java.util.Vector.lastIndexOf(ja...
arg1: TEST
....... public synchronized int java.util.Vector.lastIn...
....... arg1: TEST
....... arg2: 2
....... return -1
return -1
*JDKのProxyの代わりに使える [#a225fc5e]
なんのことかというと、あたかも元々のクラスのようにつかう...
**JDKのProxyの説明はこちら [#sccd2b29]
http://ffy.afy-system.jp/tips/t_004.html
**サンプルコード [#ffb5798e]
http://cglib.sourceforge.net/xref/samples/JdkCompatiblePr...
*java cglibでmixin [#cbef2da9]
**リンク [#q40a8740]
Java with CGLIB でMixinを使う
http://d.hatena.ne.jp/iad_otomamay/20080512/p1
**APIドキュメント [#j2a36f06]
http://www.opendocs.net/javadoc/cglib/2.2/net/sf/cglib/pr...
**その他ネタ元はこちら [#r59a6a77]
プログラマメモ2
http://programamemo2.blogspot.com/2007/07/java-cglibmixin...
**既に生成されたオブジェクトにたいして、あらたにインター...
***サンプルコード [#v588dc98]
package mixin;
import net.sf.cglib.proxy.Mixin;
public class Test {
public static void main(String[] args) {
new Test().testMixin();
}
void testMixin() {
C c = mixin(new A() {
@Override
public void a() {
System.out.println("o_o i am A!!");
}
});
/* もとの型を保持しているかチェック */
if (c instanceof A) {
((A) c).a();
}
c.c();
}
/*
* クラス配列とクラス配列を連結します。
*/
static Class[] concat(Class[] a, Class[] b) {
Class[] arr = new Class[a.length + b.length];
System.arraycopy(a, 0, arr, 0, a.length);
System.arraycopy(b, 0, arr, a.length, b.length);
return arr;
}
interface A {
public void a();
}
interface C {
public void c();
}
/*
* もとのオブジェクトにたいして、Cインターフェイスを...
*/
public C mixin(Object o) {
Class[] interfaces = concat(new Class[] { C.class...
.getInterfaces());
Object[] delegates = new Object[] { new C() {
@Override
public void c() {
System.out.println("i am C o_o!");
}
}, o };
Object obj = Mixin.create(interfaces, delegates);
C c = (C) obj;
return c;
}
}
**考察 [#i819e59c]
元にするクラスのインタフェースを用意しとかなきゃならんの...
あとで下記のドキュメントでもみてみるか。。。
[Java]動的なインターフェイスの追加(擬似的な方法)
http://d.hatena.ne.jp/daisuke-m/20081212/1229083116
*メソッド実行の前後に処理をフックをかけるというか差し込む...
元ネタサイトはこちら
**CGLIBにさわる [#k59f343f]
http://muimi.com/j/aop/cglib/
メソッド実行の前後に処理をフックをかけるというか差し込む...
元ネタの元ネタサイトは
本家
http://cglib.sourceforge.net/
Sampleの
Beansサンプルと思われる。
***掲載されていたサンプル [#h5c59501]
Foo.java
package hoge;
public class Foo {
public void doSomething(){
System.out.println("doSomethig");
}
}
Sample1.java
package hoge;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Sample1 {
public static void main(String[] args) throws Excepti...
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Foo.class);
enhancer.setCallback(new MyMethodIntercepter());
Foo foo = (Foo)enhancer.create();
foo.doSomething();
}
}
class MyMethodIntercepter implements MethodInterceptor{
public Object intercept(Object obj, Method method, Ob...
System.out.println("before");
return proxy.invokeSuper(obj, args);
}
}
実行結果
before
doSomethig
Enhancerというクラスを利用してサブクラスを作り、setCallba...
*クラスをプロキシする [#ka99d418]
http://andore.com/money/trans/spring_ref_p7_ja.html#doc8_...
*CGLIB で実行時にクラスにメソッドを追加する [#r95d066f]
URLはこちら
http://d.hatena.ne.jp/akishin999/20100604/1275611622
**サンプルコード [#k24425d2]
以下のサンプルでは、Date 型の setCreatedAt しか持たない J...
ポイントは InterfaceMaker を使ってインターフェースの定義...
package example;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import net.sf.cglib.asm.Type;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InterfaceMaker;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGLibExample {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// 新規インターフェースを定義する
InterfaceMaker im = new InterfaceMaker();
// 文字列を引数とした setCreatedAt を定義
im.add(new Signature("setCreatedAt", Type.VOID_TY...
.getType(String.class) }), null);
// インターフェースを生成
Class myInterface = im.create();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ExampleBean.class);
// 生成したインターフェースを追加する
enhancer.setInterfaces(new Class[] { myInterface ...
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method me...
MethodProxy proxy) throws Throwable {
ExampleBean bean = (ExampleBean) obj;
// 文字列を引数とした setCreatedAt が呼ば...
if (method.getName().startsWith("setCreat...
&& args[0] != null && args[0] ins...
SimpleDateFormat sdf = new SimpleDate...
Date date = null;
try {
date = sdf.parse((String) args[0]);
} catch (final Exception e) { /* nop ...
bean.setCreatedAt(date);
return null;
}
return proxy.invokeSuper(obj, args);
}
});
// Bean を生成
ExampleBean bean = (ExampleBean) enhancer.create();
bean.setId(999);
// 実行時に型を追加しているため、呼び出しはリフレ...
try {
// 追加したメソッドはあくまで CGLIB によって...
// ExampleBean.class ではなく、bean.getClass(...
Method method = bean.getClass().getMethod("se...
method.invoke(bean, new Object[]{"20100531"});
} catch (final Exception e) {
e.printStackTrace();
}
System.out.printf("id : [%d] createdAt : [%s]\n",...
}
}
/**
* サンプル用の JavaBeans
*/
class ExampleBean implements Serializable {
private static final long serialVersionUID = -8121418...
private int id;
private Date createdAt;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
}
***実行結果 [#v266c17a]
id : [999] createdAt : [Mon May 31 00:00:00 JST 2010]
*考察 [#b850091a]
インタフェースだけ定義しておいて、テスト用にモックオブジ...
分業することができる。
**jmock [#q536b48c]
http://www.jmock.org/mocking-classes.html
*[Java]Javassistとcglibにおけるメソッドフィルタの指定 [#m...
http://d.hatena.ne.jp/Kazzz/20080626/p1
cglibによるHogeクラスを拡張するEnhancerのフィルタとハンド...
Hoge enhancedHoge = Enhancer.create(Hoge.class, null
, new CallbackFilter(){
@Override
public int accept(Method method) {
return (method != null && method.getName(...
&& method.getReturnType() == bool...
&& method.getParameterTypes().len...
&& method.getParameterTypes()[0] ...
? 0 //NoOp.INSTANCEにマップする(捕捉...
: 1;
}}
, new Callback[]{NoOp.INSTANCE, new MethodInterce...
@Override
public Object intercept(Object obj, Method me...
Object[] args, MethodProxy proxy) thr...
System.out.println("*** before " + method....
proxy.invoke(obj, args);
System.out.println("*** after " + method....
}}});
*ASMとは [#m1a87732]
ASM はJavaのバイトコードを操作したり、解析するためのフレ...
既存のクラスを変更したり、動的にクラスを生成することがで...
CGLIBがこのASMをつかっています。
**ASMのページ [#p3d1db5d]
http://asm.ow2.org/
**日本語の使用例の記述 [#fc30ec3f]
簡易AOPフレームワークの作成
http://d.hatena.ne.jp/iad_otomamay/20100418/1271560826
終了行:
[[JAVAの記事一覧]]
&topicpath;
*目次 [#bca26b28]
#contents
*CGLIBとは? [#fa0ae660]
CGLIBとは、Javaコード生成ライブラリです。クラスファイルを...
**CGLIBのWebページ [#xf7e883a]
http://cglib.sourceforge.net/
*本ページの趣旨 [#x0113801]
jparsecみてたら、動的ソースコード生成のライブラリであるcg...
興味が湧いたのでまとめてみる
ついでに、サンプルのコードの説明がなかったので、自分で説...
SpringやらHibernateなんかに内部的に使われているライブラリ...
*インタフェース定義するだけでPOJO的なインスタンスを生成す...
net.sf.cglib.core.KeyFactoryのすごいのは、なんといっても...
http://cglib.sourceforge.net/xref/samples/KeySample.html
package samples;
import net.sf.cglib.core.KeyFactory;
public class KeySample {
private interface MyFactory {
public Object newInstance(int a, char[] b, Str...
}
public static void main(String[] args) {
MyFactory f = (MyFactory)KeyFactory.create(MyF...
Object key1 = f.newInstance(20, new char[]{ 'a...
Object key2 = f.newInstance(20, new char[]{ 'a'...
Object key3 = f.newInstance(20, new char[]{ 'a'...
System.out.println(key1.equals(key2));
System.out.println(key2.equals(key3));
}
}
*実行トレーサを作るサンプル [#p0328206]
http://cglib.sourceforge.net/xref/samples/Trace.html
*解説 [#t66723cd]
Enhancer クラスの使い方のサンプル
クラスのインスタンスの作成をnew ではなく
汎用的に作られたnewInstanceメソッドで生成すると
なんと、そのインスタンスのメソッドを実行するたびに、
そのメソッドをインターセプトというかフックと言うべきか横...
どこの何のメソッドが実行されているのか、パラメータは何な...
**サンプル [#o73635e1]
package samples;
import net.sf.cglib.proxy.*;
import java.util.*;
/***
*
* @author baliuka
*/
public class Trace implements MethodInterceptor {
int ident = 1;
static Trace callback = new Trace();
/*** Creates a new instance of Trace */
private Trace() {
}
public static Object newInstance( Class clazz ){
try{
Enhancer e = new Enhancer();
e.setSuperclass(clazz);
e.setCallback(callback);
return e.create();
}catch( Throwable e ){
e.printStackTrace();
throw new Error(e.getMessage());
}
}
/***
* @param args the command line arguments
*/
public static void main(String[] args) {
List list = (List)newInstance(Vector.class);
Object value = "TEST";
list.add(value);
list.contains(value);
try{
list.set(2, "ArrayIndexOutOfBounds" );
}catch( ArrayIndexOutOfBoundsException ignore ){
}
list.add(value + "1");
list.add(value + "2");
list.toString();
list.equals(list);
list.set( 0, null );
list.toString();
list.add(list);
list.get(1);
list.toArray();
list.remove(list);
list.remove("");
list.containsAll(list);
list.lastIndexOf(value);
}
public Object intercept(Object obj, java.lang.refle...
MethodProxy proxy) throws T...
printIdent(ident);
System.out.println( method );
for( int i = 0; i < args.length; i++ ){
printIdent(ident);
System.out.print( "arg" + (i + 1) + ": ");
if( obj == args[i])
System.out.println("this");
else
System.out.println(args[i]);
}
ident++;
Object retValFromSuper = null;
try {
retValFromSuper = proxy.invokeSuper(obj, ar...
ident--;
} catch (Throwable t) {
ident--;
printIdent(ident);
System.out.println("throw " + t );
System.out.println();
throw t.fillInStackTrace();
}
printIdent(ident);
System.out.print("return " );
if( obj == retValFromSuper)
System.out.println("this");
else System.out.println(retValFromSuper);
if(ident == 1)
System.out.println();
return retValFromSuper;
}
void printIdent( int ident ){
while( --ident > 0 ){
System.out.print(".......");
}
System.out.print(" ");
}
}
**実行結果 [#j90f41b1]
mainメソッドの1行1行実行されるたびに、コンソールにメッ...
public synchronized boolean java.util.Vector.add(java....
arg1: TEST
return true
public boolean java.util.Vector.contains(java.lang.Obje...
arg1: TEST
....... public synchronized int java.util.Vector.indexO...
....... arg1: TEST
....... arg2: 0
....... return 0
return true
public synchronized java.lang.Object java.util.Vector.s...
arg1: 2
arg2: ArrayIndexOutOfBounds
throw java.lang.ArrayIndexOutOfBoundsException: Array i...
public synchronized boolean java.util.Vector.add(java.l...
arg1: TEST1
return true
public synchronized boolean java.util.Vector.add(java.l...
arg1: TEST2
return true
public synchronized java.lang.String java.util.Vector.t...
....... public java.util.Iterator java.util.AbstractLis...
....... return java.util.AbstractList$Itr@13b06041
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 0
....... return TEST
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 1
....... return TEST1
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 2
....... return TEST2
....... public synchronized int java.util.Vector.size()
....... return 3
return [TEST, TEST1, TEST2]
public synchronized boolean java.util.Vector.equals(jav...
arg1: this
return true
public synchronized java.lang.Object java.util.Vector.s...
arg1: 0
arg2: null
return TEST
public synchronized java.lang.String java.util.Vector.t...
....... public java.util.Iterator java.util.AbstractLis...
....... return java.util.AbstractList$Itr@1c701a27
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 0
....... return null
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 1
....... return TEST1
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 2
....... return TEST2
....... public synchronized int java.util.Vector.size()
....... return 3
return [null, TEST1, TEST2]
public synchronized boolean java.util.Vector.add(java.l...
arg1: this
return true
public synchronized java.lang.Object java.util.Vector.g...
arg1: 1
return TEST1
public synchronized java.lang.Object[] java.util.Vector...
return [Ljava.lang.Object;@ffdadcd
public boolean java.util.Vector.remove(java.lang.Object)
arg1: this
....... public synchronized boolean java.util.Vector.re...
....... arg1: this
.............. public int java.util.Vector.indexOf(java...
.............. arg1: this
..................... public synchronized int java.util...
..................... arg1: this
..................... arg2: 0
............................ public synchronized boolea...
............................ arg1: null
............................ return false
............................ public synchronized boolea...
............................ arg1: TEST1
............................ return false
............................ public synchronized boolea...
............................ arg1: TEST2
............................ return false
............................ public synchronized boolea...
............................ arg1: this
............................ return true
..................... return 3
.............. return 3
.............. public synchronized void java.util.Vecto...
.............. arg1: 3
.............. return null
....... return true
return true
public boolean java.util.Vector.remove(java.lang.Object)
arg1:
....... public synchronized boolean java.util.Vector.re...
....... arg1:
.............. public int java.util.Vector.indexOf(java...
.............. arg1:
..................... public synchronized int java.util...
..................... arg1:
..................... arg2: 0
..................... return -1
.............. return -1
....... return false
return false
public synchronized boolean java.util.Vector.containsAl...
arg1: this
....... public java.util.Iterator java.util.AbstractLis...
....... return java.util.AbstractList$Itr@50269997
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 0
....... return null
....... public boolean java.util.Vector.contains(java.l...
....... arg1: null
.............. public synchronized int java.util.Vector...
.............. arg1: null
.............. arg2: 0
.............. return 0
....... return true
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 1
....... return TEST1
....... public boolean java.util.Vector.contains(java.l...
....... arg1: TEST1
.............. public synchronized int java.util.Vector...
.............. arg1: TEST1
.............. arg2: 0
.............. return 1
....... return true
....... public synchronized int java.util.Vector.size()
....... return 3
....... public synchronized java.lang.Object java.util....
....... arg1: 2
....... return TEST2
....... public boolean java.util.Vector.contains(java.l...
....... arg1: TEST2
.............. public synchronized int java.util.Vector...
.............. arg1: TEST2
.............. arg2: 0
.............. return 2
....... return true
....... public synchronized int java.util.Vector.size()
....... return 3
return true
public synchronized int java.util.Vector.lastIndexOf(ja...
arg1: TEST
....... public synchronized int java.util.Vector.lastIn...
....... arg1: TEST
....... arg2: 2
....... return -1
return -1
*JDKのProxyの代わりに使える [#a225fc5e]
なんのことかというと、あたかも元々のクラスのようにつかう...
**JDKのProxyの説明はこちら [#sccd2b29]
http://ffy.afy-system.jp/tips/t_004.html
**サンプルコード [#ffb5798e]
http://cglib.sourceforge.net/xref/samples/JdkCompatiblePr...
*java cglibでmixin [#cbef2da9]
**リンク [#q40a8740]
Java with CGLIB でMixinを使う
http://d.hatena.ne.jp/iad_otomamay/20080512/p1
**APIドキュメント [#j2a36f06]
http://www.opendocs.net/javadoc/cglib/2.2/net/sf/cglib/pr...
**その他ネタ元はこちら [#r59a6a77]
プログラマメモ2
http://programamemo2.blogspot.com/2007/07/java-cglibmixin...
**既に生成されたオブジェクトにたいして、あらたにインター...
***サンプルコード [#v588dc98]
package mixin;
import net.sf.cglib.proxy.Mixin;
public class Test {
public static void main(String[] args) {
new Test().testMixin();
}
void testMixin() {
C c = mixin(new A() {
@Override
public void a() {
System.out.println("o_o i am A!!");
}
});
/* もとの型を保持しているかチェック */
if (c instanceof A) {
((A) c).a();
}
c.c();
}
/*
* クラス配列とクラス配列を連結します。
*/
static Class[] concat(Class[] a, Class[] b) {
Class[] arr = new Class[a.length + b.length];
System.arraycopy(a, 0, arr, 0, a.length);
System.arraycopy(b, 0, arr, a.length, b.length);
return arr;
}
interface A {
public void a();
}
interface C {
public void c();
}
/*
* もとのオブジェクトにたいして、Cインターフェイスを...
*/
public C mixin(Object o) {
Class[] interfaces = concat(new Class[] { C.class...
.getInterfaces());
Object[] delegates = new Object[] { new C() {
@Override
public void c() {
System.out.println("i am C o_o!");
}
}, o };
Object obj = Mixin.create(interfaces, delegates);
C c = (C) obj;
return c;
}
}
**考察 [#i819e59c]
元にするクラスのインタフェースを用意しとかなきゃならんの...
あとで下記のドキュメントでもみてみるか。。。
[Java]動的なインターフェイスの追加(擬似的な方法)
http://d.hatena.ne.jp/daisuke-m/20081212/1229083116
*メソッド実行の前後に処理をフックをかけるというか差し込む...
元ネタサイトはこちら
**CGLIBにさわる [#k59f343f]
http://muimi.com/j/aop/cglib/
メソッド実行の前後に処理をフックをかけるというか差し込む...
元ネタの元ネタサイトは
本家
http://cglib.sourceforge.net/
Sampleの
Beansサンプルと思われる。
***掲載されていたサンプル [#h5c59501]
Foo.java
package hoge;
public class Foo {
public void doSomething(){
System.out.println("doSomethig");
}
}
Sample1.java
package hoge;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Sample1 {
public static void main(String[] args) throws Excepti...
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Foo.class);
enhancer.setCallback(new MyMethodIntercepter());
Foo foo = (Foo)enhancer.create();
foo.doSomething();
}
}
class MyMethodIntercepter implements MethodInterceptor{
public Object intercept(Object obj, Method method, Ob...
System.out.println("before");
return proxy.invokeSuper(obj, args);
}
}
実行結果
before
doSomethig
Enhancerというクラスを利用してサブクラスを作り、setCallba...
*クラスをプロキシする [#ka99d418]
http://andore.com/money/trans/spring_ref_p7_ja.html#doc8_...
*CGLIB で実行時にクラスにメソッドを追加する [#r95d066f]
URLはこちら
http://d.hatena.ne.jp/akishin999/20100604/1275611622
**サンプルコード [#k24425d2]
以下のサンプルでは、Date 型の setCreatedAt しか持たない J...
ポイントは InterfaceMaker を使ってインターフェースの定義...
package example;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import net.sf.cglib.asm.Type;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InterfaceMaker;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGLibExample {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
// 新規インターフェースを定義する
InterfaceMaker im = new InterfaceMaker();
// 文字列を引数とした setCreatedAt を定義
im.add(new Signature("setCreatedAt", Type.VOID_TY...
.getType(String.class) }), null);
// インターフェースを生成
Class myInterface = im.create();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ExampleBean.class);
// 生成したインターフェースを追加する
enhancer.setInterfaces(new Class[] { myInterface ...
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method me...
MethodProxy proxy) throws Throwable {
ExampleBean bean = (ExampleBean) obj;
// 文字列を引数とした setCreatedAt が呼ば...
if (method.getName().startsWith("setCreat...
&& args[0] != null && args[0] ins...
SimpleDateFormat sdf = new SimpleDate...
Date date = null;
try {
date = sdf.parse((String) args[0]);
} catch (final Exception e) { /* nop ...
bean.setCreatedAt(date);
return null;
}
return proxy.invokeSuper(obj, args);
}
});
// Bean を生成
ExampleBean bean = (ExampleBean) enhancer.create();
bean.setId(999);
// 実行時に型を追加しているため、呼び出しはリフレ...
try {
// 追加したメソッドはあくまで CGLIB によって...
// ExampleBean.class ではなく、bean.getClass(...
Method method = bean.getClass().getMethod("se...
method.invoke(bean, new Object[]{"20100531"});
} catch (final Exception e) {
e.printStackTrace();
}
System.out.printf("id : [%d] createdAt : [%s]\n",...
}
}
/**
* サンプル用の JavaBeans
*/
class ExampleBean implements Serializable {
private static final long serialVersionUID = -8121418...
private int id;
private Date createdAt;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
}
***実行結果 [#v266c17a]
id : [999] createdAt : [Mon May 31 00:00:00 JST 2010]
*考察 [#b850091a]
インタフェースだけ定義しておいて、テスト用にモックオブジ...
分業することができる。
**jmock [#q536b48c]
http://www.jmock.org/mocking-classes.html
*[Java]Javassistとcglibにおけるメソッドフィルタの指定 [#m...
http://d.hatena.ne.jp/Kazzz/20080626/p1
cglibによるHogeクラスを拡張するEnhancerのフィルタとハンド...
Hoge enhancedHoge = Enhancer.create(Hoge.class, null
, new CallbackFilter(){
@Override
public int accept(Method method) {
return (method != null && method.getName(...
&& method.getReturnType() == bool...
&& method.getParameterTypes().len...
&& method.getParameterTypes()[0] ...
? 0 //NoOp.INSTANCEにマップする(捕捉...
: 1;
}}
, new Callback[]{NoOp.INSTANCE, new MethodInterce...
@Override
public Object intercept(Object obj, Method me...
Object[] args, MethodProxy proxy) thr...
System.out.println("*** before " + method....
proxy.invoke(obj, args);
System.out.println("*** after " + method....
}}});
*ASMとは [#m1a87732]
ASM はJavaのバイトコードを操作したり、解析するためのフレ...
既存のクラスを変更したり、動的にクラスを生成することがで...
CGLIBがこのASMをつかっています。
**ASMのページ [#p3d1db5d]
http://asm.ow2.org/
**日本語の使用例の記述 [#fc30ec3f]
簡易AOPフレームワークの作成
http://d.hatena.ne.jp/iad_otomamay/20100418/1271560826
ページ名: