java反射与代理
来源:互联网 发布:2017年网络热点话题 编辑:程序博客网 时间:2024/06/05 02:51
反射,主要jdk包:java.lang.reflect
定义类 -> 创建对象 -> 通过对象操作方法、赋值或获取属性等;
定义类 -> 获取类的属性(Field)或方法对象(Method) -> 创建对象 -> 类的属性(Field)或方法对象(Method)在该对象上的调用;
类加载器加载类 <-> 类获取类加载器
ClassLoader.loadClass() <-> Class.getClassLoader();
类定义对象 <-> 对象获取类
Object obj <-> obj.getClass();
代码示例:
HelloReflect接口
public interface HelloReflect { void sayHello();}
HelloReflect接口实现类
public class HelloReflectImpl implements HelloReflect { private int id; @Override public void sayHello() { System.out.println("hello, reflect!"); }}
HelloReflect接口代理类
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class HelloReflectProxy { private HelloReflect helloReflect; public HelloReflectProxy(HelloReflect helloReflect) { this.helloReflect = helloReflect; } public HelloReflect getProxy() { HelloReflect proxy = (HelloReflect) Proxy.newProxyInstance( helloReflect.getClass().getClassLoader(), helloReflect.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy stdout begin..."); Object object = method.invoke(helloReflect, args); System.out.println("proxy stdout end..."); return object; } }); return proxy; }}
反射与jdk动态代理测试类
import java.lang.reflect.Field;import java.lang.reflect.Method;public class TestHelloReflect { public static void main(String[] args) throws Exception { HelloReflect helloReflect = new HelloReflectImpl(); //field、method Field field = HelloReflectImpl.class.getDeclaredField("id"); Method method = HelloReflectImpl.class.getDeclaredMethod("sayHello"); field.setAccessible(true); field.set(helloReflect, 1); System.out.println(field.get(helloReflect)); method.invoke(helloReflect); //proxy、invocationHandler HelloReflectProxy helloReflectProxy = new HelloReflectProxy(helloReflect); helloReflect = helloReflectProxy.getProxy(); helloReflect.sayHello(); }}
jdk动态代理:
利用的是被代理类的接口生成的代理类,代理类里会有一个被代理类对象,在调用代理类的方法时,实际上是通过代理类里InvocationHandler对象的invoke方法通过反射来调用被代理类的方法,在invoke这个方法里可以对method做不同判断和处理,实现不同的切面功能等,代理类与被代理类之间是实现的相同接口,所以只能代理接口方法,代理类对象里包含一个被代理类的对象,代理类与被代理类之间是”兄弟”关系
另一种动态代理:cglib,Code Generation Library
需要引入第三方jar包:cglib或cglib-nodep,cglib包需要引入asm包,部分老版本cglib包没有包含asm包、需要单独引入,cglib-nodep包没有asm包、不需要asm包
<dependencies> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.5</version> </dependency></dependencies>
代码示例:
HelloCglib类,不需实现接口
public class HelloCglib { public final void testFinal() { System.out.println("TestFinal, Cglib!"); } public void sayHello() { System.out.println("Hello, Cglib!"); } public void sayHehe() { System.out.println("Hehe, Cglib!"); }}
HelloCglib代理对象方法回调过滤器
import net.sf.cglib.proxy.CallbackFilter;import java.lang.reflect.Method;public class HelloCglibCallbackFilter implements CallbackFilter { @Override public int accept(Method method) { if("sayHello".equals(method.getName()) || "testFinal".equals(method.getName())) { return 1; } if("sayHehe".equals(method.getName())) { return 2; } return 0; }}
HelloCglib代理对象sayHello方法拦截器
import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class HelloCglibSayHelloInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib say hello interceptor stdout begin..."); Object object = methodProxy.invokeSuper(o, objects); System.out.println("cglib say hello interceptor stdout end..."); return object; }}
HelloCglib代理对象sayHehe方法拦截器
import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class HelloCglibSayHeheInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib say hehe interceptor stdout begin..."); Object object = methodProxy.invokeSuper(o, objects); System.out.println("cglib say hehe interceptor stdout end..."); return object; }}
HelloCglib代理对象测试类
import net.sf.cglib.proxy.Callback;import net.sf.cglib.proxy.CallbackFilter;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.NoOp;public class TestHelloCglib { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(HelloCglib.class); CallbackFilter callbackFilter = new HelloCglibCallbackFilter(); Callback defaultCallBack = NoOp.INSTANCE; Callback helloCglibSayHelloInterceptor = new HelloCglibSayHelloInterceptor(); Callback helloCglibSayHeheInterceptor = new HelloCglibSayHeheInterceptor(); Callback[] callbacks = new Callback[]{defaultCallBack, helloCglibSayHelloInterceptor, helloCglibSayHeheInterceptor}; enhancer.setCallbackFilter(callbackFilter); enhancer.setCallbacks(callbacks); HelloCglib helloCglib = (HelloCglib) enhancer.create(); helloCglib.testFinal(); helloCglib.sayHello(); helloCglib.sayHehe(); }}
cglib动态代理
需引入第三方包,被代理对象无需实现接口,代理对象是被代理对象的子类,两者属于”父子”关系,代理类无法代理被代理类的final方法,无法Override所以还是调用的父类被代理对象的final方法
cglib代理逻辑:代理类调用方法 -> CallbackFilter方法回调过滤器 -> Callback方法拦截(前置处理 -> methodProxy.invokeSuper(o, objects) -> 后置处理),如果只有单个Callback方法拦截器,且拦截所有方法,则无需设置CallbackFilter
Enhancer类的一些创建方法:
Enhancer.create();//该方法需单独设置superclass等信息
Enhancer.create(Class superclass, Callback callback);
Enhancer.create(Class superclass, Class[] interfaces, Callback callback);
Enhancer.create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks);
另外,cglib包里也实现了类似于jdk里的基于接口的动态代理,使用方法和jdk里的动态代理类似,只不过引入的包需换成net.sf.cglib.proxy包
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class TestHelloReflect2 { public static void main(String[] args) { final HelloReflect helloReflect = new HelloReflectImpl(); HelloReflect helloReflectProxy = (HelloReflect) Proxy.newProxyInstance( helloReflect.getClass().getClassLoader(), helloReflect.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("cglib proxy stdout begin..."); Object object = method.invoke(helloReflect, args); System.out.println("cglib proxy stdout end..."); return object; } }); helloReflectProxy.sayHello(); }}
- JAVA反射与代理
- Java反射与代理
- Java反射与代理
- java反射与代理
- Java反射与动态代理
- java的反射与代理
- JAVA的反射与代理
- java反射与动态代理
- java反射与动态代理
- Java反射与动态代理
- Java反射与动态代理
- Java 反射与动态代理
- Java反射与动态代理
- 【反射】JAVA代理模式与动态代理
- JAVA中代理与反射的应用
- java反射机制与动态代理
- Java反射机制与动态代理
- java代理模式与反射机制
- 一个简单的压缩成tar.gz文件的shell脚本
- [编程题] 藏宝图
- 6.4
- 指针问题梳理
- git问题:You have not concluded your merge (MERGE_HEAD exists)
- java反射与代理
- Mac安装OpenCV(用于虚拟环境)
- Ubuntu14.04下编译pycaffe并绘制网络结构图
- 中国计算机学会推荐国际学术期刊
- 11月9日心得
- jQuery选择器
- BZOJ 4390: [Usaco2015 dec]Max Flow
- 谷歌浏览器 OVER THE WALL 插件的使用
- Linux的初步学习(2)