java反射与代理

反射,主要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();

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值