CGlib 入门

CGlib 入门CGlib 入门 cglib github 地址链接 项目 maven 构建 cglib cglib 3 1 pre p 项目 gradle 构建 p pre class language javascript dependencies compile cglib cglib 3 1 testCompile junit junit 4 11

CGlib 入门

cglib github地址链接。

项目maven构建:


cglib
cglib
3.1

/pre>

p>项目gradle构建:

/p>

pre class='language-javascript'>

dependencies { compile 'cglib:cglib:3.1' testCompile 'junit:junit:4.11' }

/pre>

p>cglib不仅可以动态创建实现了接口类的代理对象,还可以为简单的POJO动态创建代理对象;而java只能动态创建实现了接口类的代理对象(使用Proxy类和InvocationHandler接口)。

/p>

h4>1,Enhancer和FixedValue

/h4>

p>cglib中最重要的就是net.sf.cglib.proxy.Enhancer这个类,与java中的Proxy类有异曲同工之妙,都可以创建代理对象。

/p>

p>下面就来简单实验一下:


首先新建一个简单的POJO类CGlibSample.java

/p>

pre class='language-javascript'>

public class CGlibSample {


public String test(String input){
return input;
}
}

/pre>

p>测试类TestCG.java:

/p>

pre class='language-javascript'>

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.FixedValue;
import org.junit.Assert;
import org.junit.Test;

public class TestCG {


@Test
public void testFixedValue() throws Exception {

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(CGlibSample.class);

/*enhancer.setCallback(new FixedValue() { @Override public Object loadObject() throws Exception { return "Hello cglib!"; } });*/

//java lambda expression 与上面的代码段效果一样
enhancer.setCallback((FixedValue)() -> {
return "Hello cglib!";
});

CGlibSample proxy = (CGlibSample)enhancer.create();

Assert.assertEquals("Hello cglib!",proxy.test("hello!"));
Assert.assertEquals("Hello cglib!",proxy.toString());
Assert.assertFalse("hello!".equals
(proxy.test("hello!")));

}
}

/pre>

p>这里的FixedValue接口相当于一个拦截器(interceptor)。 proxy.getClass() 输出结果为 class glib.CGlibSample

/p>

p>EnhancerByCGLIB

/p>

p>c9fa3aa1,明显可以看这是个有cglib产生的代理对象,目标对象为glib.CGlibSample 由以上代码可得cglib可以改变方法。 注意: 创建代理对象的目标对象(这里是CGlibSample)一定要有无参构造方法

/p>

h4>2,InvocationHandler

/h4>

p>这里的InvocationHandler接口并不是java反射包中的InvocationHandler,而是cglib中接口net.sf.cglib.proxy.InvocationHandler,其实里面的内容和java差不多,如下所示:

/p>

pre class='language-javascript'>

public interface InvocationHandler extends Callback {

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;

}

/pre>

pre class='language-javascript'>

@Test
public void testInvocationHandler(){

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(CGlibSample.class);

enhancer.setCallback(new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
/** * method.getDeclaringClass() != Object.class 表示该方法不能是Object类中定义的方法,如:toString()。 * method.getReturnType() == String.class 表示方法的返回类型只能为String类型 */
if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return "Hello cglib!";
} else {
return "do not know what to do";
}
}
});

CGlibSample proxy = (CGlibSample) enhancer.create();

Assert.assertTrue("Hello cglib!".equals(proxy.test("hello!")));

Assert.assertTrue("do not know what to do".equals(proxy.toString()));

}

/pre>

h4>3,MethodInterceptor

/h4>

pre class='language-javascript'>

@Test
public void testMethodInterceptor(){

Enhancer enhancer = new Enhancer();

enhancer.setSuperclass(CGlibSample.class);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return "Hello cglib!";
} else {
//这里有点像struts2中拦截器链
return proxy.invokeSuper(obj,args);
}
}
});

CGlibSample proxy = (CGlibSample) enhancer.create();

Assert.assertTrue("Hello cglib!".equals(proxy.test("hello!")));

Assert.assertFalse("do not know what to do".equals(proxy.toString()));
}

/pre>

h4>4,CallbackFilter

/h4>

p>接口CallbackFilter实现类CallbackHelper。

/p>

pre class='language-javascript'>

@Test
public void testCallbackFilter(){

Enhancer enhancer = new Enhancer();

CallbackHelper callbackHelper = new CallbackHelper(CGlibSample.class,new Class[0]) {
@Override
protected Object getCallback(Method method) {
if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
return new FixedValue() {
@Override
public Object loadObject() throws Exception {
return "Hello cglib!";
}
};
} else {
return NoOp.INSTANCE;
}
}
};

enhancer.setSuperclass(CGlibSample.class);
enhancer.setCallbackFilter(callbackHelper);
enhancer.setCallbacks(callbackHelper.getCallbacks());

CGlibSample proxy = (CGlibSample) enhancer.create();

Assert.assertTrue("Hello cglib!".equals(proxy.test("hello!")));
System.out.println(proxy.hashCode());
Assert.assertFalse("do not know what to do".equals(proxy.toString()));

/pre>

p>注意:不要使用非静态的匿名内部类,会造成内存泄露。本文使用非静态的匿名内部类是为了方便。

/p>

h4>5,Immutable Bean

/h4>

pre class='language-javascript'>

@Test(expected = java.lang.IllegalStateException.class)
public void testImmutableBean(){

SampleBean sampleBean = new SampleBean();

sampleBean.setValue("Hello cglib");

SampleBean immutableBean = (SampleBean) ImmutableBean.create(sampleBean);

Assert.assertTrue("Hello cglib".equals(immutableBean.getValue()));

sampleBean.setValue("Hello cglib again");
Assert.assertTrue("Hello cglib again".equals(immutableBean.getValue()));

immutableBean.setValue("Hello World!");//throw Exception java.lang.IllegalStateException: Bean is immutable
}

/pre>

h4>6,Bean Generator

/h4>

pre class='language-javascript'>

@Test
public void testBeanGenerator() throws Exception{

BeanGenerator beanGenerator = new BeanGenerator();

beanGenerator.addProperty("value",String.class);

Object bean = beanGenerator.create();
//获取bean的setter方法
Method setter = bean.getClass().getMethod("setValue",String.class);
setter.invoke(bean,"Hello cglib");

//获取bean的getter方法
Method getter = bean.getClass().getMethod("getValue");

Assert.assertTrue("Hello cglib".equals(getter.invoke(bean)));


}

/pre>

h4>7,Bean Copier

/h4>

p>OtherSampleBean:

/p>

pre class='language-javascript'>

public class OtherSampleBean {


private String value;

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}
}

/pre>

p>测试案例:

/p>

pre class='language-javascript'>

@Test
public void testBeanCopier(){

BeanCopier copier = BeanCopier.create(SampleBean.class,OtherSampleBean.class,false);

SampleBean sampleBean = new SampleBean();
sampleBean.setValue("sample bean");

OtherSampleBean otherSampleBean = new OtherSampleBean();
copier.copy(sampleBean,otherSampleBean,null);

Assert.assertTrue("sample bean".equals(otherSampleBean.getValue()));
}

/pre>

h4>8,Bulk Bean

/h4>

pre class='language-javascript'>

@Test
public void testBulkBean(){

BulkBean bulkBean = BulkBean.create(SampleBean.class,
new String[]{

"getValue"},
new String[]{

"setValue"},
new Class[]{String.class});

SampleBean bean = new SampleBean();
bean.setValue("sample bean");

Assert.assertTrue(bulkBean.getPropertyValues(bean).length == 1);

Assert.assertTrue("sample bean".equals(bulkBean.getPropertyValues(bean)[0]));

bulkBean.setPropertyValues(bean,new Object[]{

"bulk bean"});

Assert.assertTrue("bulk bean".equals(bean.getValue()));
}

/pre>

h4>9,Bean Map

/h4>

pre class='language-javascript'>

@Test
public void testBeanMap(){

SampleBean bean = new SampleBean();

BeanMap map = BeanMap.create(bean);
bean.setValue("bean mao");

Assert.assertTrue("bean mao".equals(map.get("value")));

}

/pre>

编程小号
上一篇 2025-03-18 20:57
下一篇 2025-02-19 11:01

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/hz/109683.html