通过泛型反射和cglib动态代理方式创建代理对象

     动态代理的方式有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

    


  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值