Java 代理模式之三:Cglib动态代理

前面写了代理模式的两种方法:JDK的静态代理和JDK的动态代理。

本文继续以小Demo为例,写第三种代理:Cglib动态代理。

接口:

/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :IUser.java<br>
 * @类描述 :<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:34:02<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
package com.andy.proxy.cglib;

/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :IUser.java<br>
 * @类描述 :接口名<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:34:02<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
public interface IUser {
	public void eat(String food);
}
逻辑实现类,但并没有实现接口:


/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :UserImpl.java<br>
 * @类描述 :<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:34:42<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
package com.andy.proxy.cglib;

/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :UserImpl.java<br>
 * @类描述 :逻辑实现类,并没有实现接口<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:34:42<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
public class UserImpl {

	public void eat(String food) {
		// TODO Auto-generated method stub
		System.out.println("吃" + food);
	}

}
接口逻辑实现类,实现接口:


/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :UserImpl2.java<br>
 * @类描述 :<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午04:01:49<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
package com.andy.proxy.cglib;

/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :UserImpl2.java<br>
 * @类描述 :接口逻辑实现类<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午04:01:49<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
public class UserImpl2 implements IUser {

	/* (non-Javadoc)
	 * @see com.andy.proxy.cglib.IUser#eat(java.lang.String)
	 */
	public void eat(String food) {
		// TODO Auto-generated method stub
		System.out.println("吃" + food);
	}

}
代理类:


/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :UserCglib.java<br>
 * @类描述 :<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:40:31<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
package com.andy.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :UserCglib.java<br>
 * @类描述 :Cglib实现动态代理<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:40:31<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
public class UserCglib implements MethodInterceptor {
	private Object proxyObject;

	/**
	 * 
	 * 方法名 :getInstance<br>
	 * 方法描述 :创建代理对象<br>
	 * 创建者 :Andy.wang<br>
	 * 创建时间 :2013-8-26下午03:47:36 <br>
	 * 
	 * @param proxyObject
	 * @return 返回类型 :Object
	 */
	public Object getInstance(Object proxyObject) {
		this.proxyObject = proxyObject;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.proxyObject.getClass());
		// 回调方法
		enhancer.setCallback(this);
		// 创建代理对象
		return enhancer.create();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object,
	 * java.lang.reflect.Method, java.lang.Object[],
	 * net.sf.cglib.proxy.MethodProxy)
	 */
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("事物开始");
		proxy.invokeSuper(obj, args);
		System.out.println("事物结束");
		return null;
	}

}
测试类:


/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :CglibTest.java<br>
 * @类描述 :<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:50:19<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
package com.andy.proxy.cglib;

/**
 * @包名 :com.andy.proxy.cglib<br>
 * @文件名 :CglibTest.java<br>
 * @类描述 :Cglib动态代理测试<br>
 * @作者 :Andy.wang<br>
 * @创建时间 :2013-8-26下午03:50:19<br>
 * @更改人 :<br>
 * @更改时间 :<br>
 */
public class CglibTest {
    public static void main(String[] args) {
        UserCglib cglib = new UserCglib();
        // 注意cglib.getInstance()的参数,及接收返回值的类型
        
        // 没有实现接口
        UserImpl user = (UserImpl) cglib.getInstance(new UserImpl());
        user.eat("苹果");
        
        System.out.println(".........");
        
        // 实现接口
        IUser user2 = (IUser) cglib.getInstance(new UserImpl2());
        user2.eat("香蕉");
        
        System.out.println(".........");
        
        // 实现接口
        UserImpl2 user3 = (UserImpl2) cglib.getInstance(new UserImpl2());
        user3.eat("橘子");
        
        System.out.println(".........");
        
        // 没有实现接口
        IUser user4 = (IUser) cglib.getInstance(new UserImpl());
        user4.eat("桃子");
        
    }
}

输出结果:

事物开始
吃苹果
事物结束
.........
事物开始
吃香蕉
事物结束
.........
事物开始
吃橘子
事物结束
.........
Exception in thread "main" java.lang.ClassCastException: com.andy.proxy.cglib.UserImpl$$EnhancerByCGLIB$$20da88ad cannot be cast to com.andy.proxy.cglib.IUser
    at com.andy.proxy.cglib.CglibTest.main(CglibTest.java:45)

结论:UserImpl类和UserImpl2类只是做一个对比,一个实现接口,一个没实现接口。

由测试结果可以看出 动态代理类的方法getInstance(Object obj)所返回的类型,必须所依赖的

参数类型一致,或者与所依赖的参数类型的父类一致。


你可能感兴趣的:(动态代理,java设计模式,cglib,代理模式)