反射的基本使用
使用反射调用类中的方法
反射调用静态方法
1 2 3
| Class cl = Class.forName("cn.zl.mqdemo.MyReflect"); Method m = cl.getMethod("staticMd"); m.invoke(cl);
|
反射调用公有方法
1 2 3 4
| //反射调用公有方法 Object obj = cl.newInstance(); Method m = cl.getMethod("publicMd"); m.invoke(obj);
|
反射调用私有方法
1 2 3 4
| //反射调用私有方法 Method method = cl.getDeclaredMethod("privateMd"); method.setAccessible(true); method.invoke(obj);
|
如果是调用私有犯法,还得加入method.setAccessible(true);
私有方法的获取并不是通过 getMethod() 方式,而是通过 getDeclaredMethod() 获取的。
JDK 原生动态代理
JDK Proxy 只能代理实现接口的类(即使是 extends 继承类也是不可以代理的)。
示例代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class 动态代理 {
public static void main(String[] args) { // JDK 动态代理调用 AnimalProxy proxy = new AnimalProxy(); Animal dogProxy = (Animal) proxy.getInstance(new Dog()); dogProxy.eat(); }
} interface Animal { void eat(); } class Dog implements Animal { @Override public void eat() { System.out.println("The dog is eating"); } } class Cat implements Animal { @Override public void eat() { System.out.println("The cat is eating"); } } class AnimalProxy implements InvocationHandler{ Object target; //代理对象 public Object getInstance(Object target) { this.target = target; // 取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("调用前"); Object result = method.invoke(target, args); // 方法调用 System.out.println("调用后"); return result; } }
|
cglib实现动态代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class CglibProxy implements MethodInterceptor { private Object target; // 代理对象 public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); // 设置父类为实例类 enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("调用前"); Object result = methodProxy.invokeSuper(o, objects); // 执行方法调用 System.out.println("调用后"); return result; } }
|
cglib 底层是通过子类继承被代理对象的方式实现动态代理的,因此代理类不能是最终类(final),否则就会报错 java.lang.IllegalArgumentException: Cannot subclass final class xxx。