反射复习笔记 (4)

代理类:

package com.eh.test; // 代理类 public class ProxyClothFactory implements ClothFactory { private ClothFactory factory; public ProxyClothFactory(ClothFactory factory) { this.factory = factory; } @Override public void produceCloth() { System.out.println("代理工厂做了一些准备工作"); factory.produceCloth(); System.out.println("代理工厂做了一些后续工作"); } }

被代理类:

public class NikeClothFactory implements ClothFactory { @Override public void produceCloth() { System.out.println("Nike生产了一批运动服"); } }

测试类:

package com.eh.test; public class StaticProxyTest { public static void main(String[] args) { // 创建被代理类对象 NikeClothFactory nikeClothFactory = new NikeClothFactory(); // 创建代理类对象 ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nikeClothFactory); proxyClothFactory.produceCloth(); } } 动态代理

动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象

代码实现(JDK动态代理)

接口:

package com.eh.test; interface Human { String getBelief(); void eat(String food); }

被代理类

// 被代理类 public class SuperMan implements Human { @Override public String getBelief() { return "I believe I can fly"; } @Override public void eat(String food) { System.out.println("我喜欢吃" + food); } }

代理类

public class ProxyFactory { public static Object getProxyInstance(Object obj) { MyInvocationHandler myInvocationHandler = new MyInvocationHandler(); myInvocationHandler.bind(obj); return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), myInvocationHandler); } } class MyInvocationHandler implements InvocationHandler { // 定义被代理类的对象 private Object object; public void bind(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 该 method 为代理类对象的方法,也可以作为被代理的方法调用 Object invokeValue = method.invoke(object, args); // 上述方法(被代理类对象的方法)的返回值 return invokeValue; } }

测试类

public class Test { public static void main(String[] args) { SuperMan superMan = new SuperMan(); Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan); String belief = proxyInstance.getBelief(); proxyInstance.eat("食物"); } }

AOP切面编程就充分的体现出动态代理的优势

原理:只需在invoke方法中编辑自己想要添加的方法

反射常见的面试问题

通过new的方式或反射的方式都可以调用公共并的结构,开发中应该用哪个?

一般情况下建议使用new的方式,当设计到创建的对象的动态性的时候建议使用反射

反射机制与面向对象中的封装性是不是矛盾,如何看待这两个技术?

答:不矛盾,面向对象的封装性是是为了建议并提示开发者不去直接使用私有的方法属性及构造器,尽量去调用其设计者设计的public公有方法;而反射机制可以处理一些极端情况,有些开发者可能就要使用用封装好的类里面的私有方法属性或者构造器,反射机制就为这类人提供了这样操作的可能,而且反射还有更多其他的应用,比如常见的Spring框架就是以反射为基础

写一个ArrayList的动态代理类

public static void main(String[] args) { final ArrayList<String> list = new ArrayList<>(); List<String> proxyInstance = (List<String>) Proxy.newProxyInstance(list.getClass().getClassLoader(), list.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("pre-------------"); return method.invoke(list, args); } }); proxyInstance.add("hello"); System.out.println(list); }

动静态代理的区别,什么场景使用?

静态代理:

静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类,静态代理事先知道要代理的是什么,而动态代理不知道要代理什么东西,只有在运行时才知道。

动态代理:

动态代理是实现 JDK 里的 InvocationHandler 接口的 invoke 方法,但注意的是代理的是接口,也就是业务类必须要实现接口,通过 Proxy 里的 newProxyInstance 得到代理对象

还有一种动态代理 CGLIB,代理的是类,不需要业务类继承接口,通过派生的子类来实现代理。通过在运行时,动态修改字节码达到修改类的目的

AOP 编程就是基于动态代理实现的,比如著名的 Spring 框架、Hibernate 框架等等都是动态代理的使用例子

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygxjs.html