Java 动态代理实例

程序的代理模式:
当一个对象不能直接操作另一个对象时采用代理(Proxy)模式。在代理模式中可以添加一些其他业务逻辑如:日志操作、权限控制等。
代理的实现方式有两种:
1.静态代理:通过程序硬编码,为目标类做一层封装,但最终操作的还是目标类;
2.动态代理:在运行期生成目标对象的代理对象。
本为主要讲述动态代理的两种实现方式:JDK动态代理、CGLIB动态代理。
实例:
A.定义目标类与其扩展的接口

//定义一个学习接口
package phda.proxy;
public interface Study {
	public void study(String name);//提供一个学习方法
}
//其扩展类
package phda.proxy;
public class Robot implements Study {
	public void study(String name) {
		System.out.println("机器人 :"+name+" learn");
	}
}

B.JDK动态代理实现:

package phda.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * jdk 动态代理测试
 * @author Administrator
 *
 */
public class JDKProxy {
	public static Object getProxyObject(final Object c){
			return Proxy.newProxyInstance(c.getClass().getClassLoader(),//目标类的classLoader
										  c.getClass().getInterfaces(), //目标类有实现的接口
										  new InvocationHandler() {
					
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("可以定义一些其他业务操纵:日志操作");
						System.out.println("JDK代理实现:"+method.getName());
						return method.invoke(c, args);
					}
				});
	}
	
	public static void main(String[] args) {
		Robot r = new Robot();//这是直接获得对象
		//r.study("jiqiren");
		Study r2 =(Study)JDKProxy.getProxyObject(r);//获得一个代理对象
		r2.study("代理对象");
	}
}

说明:
1.使用jdk 动态代理,目标类必须要有扩展的接口;
2.代理生成的对象,为目标类扩展接口第一个接口的类型的对象,如上面的接口“Study”;==>t.getClass().getInerfaces() 数组中的第一个元素
打印结果:

可以定义一些其他业务操纵:日志操作
JDK代理实现:study
机器人 :代理对象 learn

C.CGLIB代理实现:

package phda.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * cglib 代理
 * @author Administrator
 *
 */
public class CGLIBObject {
	
	 public static Object getPoxyObject(Object c) {
         Enhancer enhancer = new Enhancer();
         enhancer.setSuperclass(c.getClass());
         enhancer.setCallback(new MethodInterceptor() {
        	 public Object intercept(Object arg0, Method arg1, Object[] arg2,
        			 				 MethodProxy arg3) throws Throwable {
        		 System.out.println("CGLIB动态代理:"+arg1.getName());
        		arg3.invokeSuper(arg0, arg2);
				return null;
			}
		});
         return enhancer.create();
   }
	 
public static void main(String[] args) {
	Robot r = new Robot();
	Study r2 =(Robot) CGLIBObject.getPoxyObject(r);
	r2.study("nini");
}	
}

说明:
1.这种代理没有接口的限制;
2.代理生成的对象可以是目标对象类型,也可以是接口的扩展类型;

资源下载
动态代理实例下载

补充:
代理模式的优点:
在不该改变被代理类的基础上,对已有的类进行功能扩展或附加。例如:权限控制、日志记录等
动态代理与静态代理之间的区别:
静态代理,以编码的方式需要实现被代理类的各个方法,这样做增加了编码量;动态代理,可以将生成代理类的方法写成公共方法,只需要传递类(xx.class)就可以获取到对应的被代理对象。同时,不用逐个编写被代理类的方法。有现成的生成代理的类,使代理模式实现更加简单,让我们更加关注业务。

动态代理静态代理
逐个实现被代理类的方法需要不需要
编码量
灵活度

【灵活度:采用静态代理,要为每个被代理类写响应的代理类,而动态代理不需要】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值