动态代理的方式有JDK的基于接口和cglib的动态代理,在spring中使用的动态代理也是这两种,综合比较而言,cglib更为强大,原因在于jdk实现依赖于被代理对象一定要实现了某一接口,是基于接口的。而Cglib则是基于类的。
这篇文章纯属入门级,希望对大家有所帮助,废话不多说了,开始贴代码。
第一:环境
使用maven进行依赖管理(建议使用maven,因为cglib的依赖包asm版本一定要和cglib匹配,在此不做整理了)。如果不使用maven,也可以手动下载cglib-2.2.2.jar和asm-3.3.1.jar。
第二:贴代码
创建工厂基类
package com.alex.cat;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import javax.management.RuntimeErrorException;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* @author alex
*
* @param <C>
*/
public class AnimalFactory<C> {
private Class<C> clazz;
/**
* 空参构造-获取泛型参数实例类型
*/
@SuppressWarnings("unchecked")
public AnimalFactory(){
//获取当前对象的class对象,因为我们使用的是本类的子类创建实例,
//因此this指子类实例,如 new CatFactory();
Class<?> clazz = this.getClass();
//获取其父类对象类型,也就是本类的泛型参数类型,也就是
//com.alex.cat.AnimalFactory<com.alex.cat.CommonCat>
Type superclass = clazz.getGenericSuperclass();
System.out.println("superclass:"+superclass);
//判断父类类型是否为参数化类型,也就是说泛型变量有没有被获取实际类型参数
if (superclass instanceof ParameterizedType) {
//获取第一个泛型参数类型,因为我们这里只有一个泛型参数C,因此就指代C
Type type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
//强转为我们要用的实际类型C,com.alex.cat.CommonCat
this.clazz = (Class<C>)type;
System.out.println("this.clazz:"+this.clazz);
}
}
/**cglib创建泛型对象的代理对象proxy
* @return
*/
@SuppressWarnings("unchecked")
public C newInstance() {
C cInstance = null;
Enhancer enHancer = new Enhancer();//创建增强对象
//设置要增强的目标类,指定其为父类,下面还是利用多态原理
enHancer.setSuperclass(this.clazz);
//设置回调方法,通过继承MethodInterceptor接口,实现方法的拦截
enHancer.setCallback(new MethodInterceptor() {
public Object intercept(Object obj, Method method, Object[] params,
MethodProxy proxy) throws Throwable {
System.out.println("...before enHance...");//前增强
Object result = proxy.invokeSuper(obj, params);//目标方法
System.out.println("...after enHance...");//后增强
if (result instanceof String) {
result = result+"... i am after enHance";
}
return result;//目标方法返回结果
}
});
cInstance = (C)enHancer.create();
if (cInstance == null) {
throw new RuntimeException("proxy对象创建失败,请重试...");
}
return cInstance;
}
}
POJO类
package com.alex.cat;
public class CommonCat {
public void catchMouse() {
System.out.println("eat the mouse...");
}
public void sleep() {
System.out.println("sleep a little time...");
}
public String talk(String name,String message) {
return name + "say:" + message;
}
}
具体工厂类
package com.alex.cat;
public class CatFactory extends AnimalFactory<CommonCat> {
}
测试类
package com.alex.cat;
public class MyMain {
public static void main(String[] args) {
CatFactory factory = new CatFactory();
CommonCat cat = factory.newInstance();
cat.catchMouse();
System.out.println("------first分割线-------");
cat.sleep();
System.out.println("------second分割线-------");
String talk = cat.talk("薛定谔的猫", "I'm the most powerful cat...");
System.out.println(talk);
}
}
执行结果
superclass:com.alex.cat.AnimalFactory<com.alex.cat.CommonCat>
this.clazz:class com.alex.cat.CommonCat
...before enHance...
eat the mouse...
...after enHance...
------first分割线-------
...before enHance...
sleep a little time...
...after enHance...
------second分割线-------
...before enHance...
...after enHance...
薛定谔的猫say:I'm the most powerful cat...... i am after enHance