黑马程序员------代理

                                                                                      ------- android培训java培训、期待与您交流! ----------


代理的概念和作用

为实现相同接口的目标类的各个方法添加一些系统功能,如工作日志、性能测试、权限控制等。

 面向方面的编程(AOP):系统存在交叉业务、一个交叉业务要切入到系统中的一个面。

黑马程序员——代理(基础加强) - zhixing5010 - zhixing5010的博客
 

 上图中的安全、事物、日志管理就是交叉事物。

动态代理

如果为每个类编写一个代理类,工作量巨大。所以jvm可以 动态的生成代理类。 

JVM可以在运行期间动态的生成类的字节码,这种动态类往往被用作代理类,即动态代理类。

JVM动态生成代理类的条件:

1)Jvm生成动态类的必须实现一个或者多个接口,所以,jvm生成的动态类只能用作具有相同接口的目标类的代理类

2)CGLIB库可以动态的生成一个类的子类,这个子类可以用做该类的代理。

代理类添加功能的位置:

1、目标方法之前。

2、目标方法之后。

3、目标方法的前后。

4、可以在try catch块中



定义一个简单的动态代理类:

先自定义一个接口。

   

package com.heima.proxy; //自定以一个接口 public interface Myinterface { //接口中的一个方法。 public void sayHello(String str); }

然后再定义一个实现了 Myinterface 接口的类

package com.heima.proxy; //定义一个实现了Myinterface接口的类 public class MyClassDemo implements Myinterface { //实现sayHello方法 @Override public void sayHello(String str) { System.out.println(str); } }

通过Proxy产生一个 MyClassDemo 的代理类:

package com.heima.proxy; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyDemo { /** * @param args */ public static void main(String[] args) throws Exception { // 通过Proxy得到一个基于Myinterface接口的代理类的class。 Class clazz=Proxy.getProxyClass(Myinterface.class.getClassLoader(), Myinterface.class); //通过反射得到代理类的构造方法 Constructor constr =clazz.getConstructor(InvocationHandler.class); //构造一个代理类的实例 Myinterface proxy = (Myinterface) constr.newInstance( new InvocationHandler(){ //创建目标类 MyClassDemo my = new MyClassDemo(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //在执行目标类的目标方法之前调用的代码 System.out.println("调用之前的代码"); //执行目标方法并且获得返回值 Object obj= method.invoke(my, args); //在执行目标类的目标方法之后调用的代码 System.out.println("调用之后的代码"); return obj; } } ); //通过代理类调用目标方法 proxy.sayHello("hello world"); } }


执行后的结果 :

调用之前的代码

hello world

调用之后的代码


然后将产生代理的方法做成通用的方法。 

package com.heima.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Collection; public class ProxyDemo { /** * @param args */ public static void main(String[] args) throws Exception { ArrayList<String > list = new ArrayList<String >(); Advice advice = new Advice(); //获得代理类 Collection<String> proxy = (Collection) getMyProxy(list,advice); //验证是否调用了目标类的方法 System.out.println(list.size()); //通过代理类调用目标方法 proxy.add("adb"); //验证是否调用了目标类的方法 System.out.println(list.size()); } public static Object getMyProxy(Object target,Advice advice) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { final Object mytarget =target; final Advice madvice =advice; //检查目标类、目标类的接口、advice类是否为空 if(target ==null||target.getClass().getInterfaces()==null||advice==null) { throw new RuntimeException("目标或者建议类为空"); } Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader() , target.getClass().getInterfaces() , new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行目标方法之前执行的操作 madvice.doBefore(); //执行目标方法 Object result =method.invoke(mytarget, args); //执行方法之后执行的操作 madvice.doAfter(); return result; } }); return proxy; } }


执行结果:

0

执行方法之前

执行方法之后

1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值