01_动态代理

一、简介

1、定义

指代理类对象在程序运行时由JVM根据反射机制动态生成的,动态代理不需要定义代理类的java源文件
JDK运行期间,动态创建class字节码并加载到JVM
动态代理的实现方式:JDK动态代理,CGLIB动态代理

2、JDK动态代理

基于java的反射机制实现,使用jdk中接口和类实现代理对象的动态创建
jdk的动态要求目标对象必须实现接口
InvocationHandler,Method,Proxy;

  • 使用步骤
a.创建接口,定义目标类要完成的功能
b.创建目标类实现接口
c.创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能:
	调用目标方法
	功能增强
d.使用proxy类的静态方法,创建代理对象

3、CGLIB动态代理

cglib是第三方的工具库,创建代理对象,cglib的原理是继承,cglib通过继承目标类,创建它的子类,在子类中重写父类中同名的方法,实现功能的修改;
因为cglib继承,重写方法,所以要求目标类不能是final的,方法也不能是final的,cglib的要求目标类比较宽松,只要能继承就可以了,在mybatis和spring AOP中都有使用;且效率高于JDK

二、使用

1、jdk动态代理

@SpringBootTest
public class Test {

    @org.junit.jupiter.api.Test
    public void testProducer() {
        ZhangSan zhangSan = new ZhangSan();
        SpeakerProxy speakerProxy = new SpeakerProxy();
        speakerProxy.setObject(zhangSan);
        Speaker speaker = (Speaker) Proxy.newProxyInstance(zhangSan.getClass().getClassLoader(), new Class[]{Speaker.class},speakerProxy);
        speaker.speak();
    }


    interface Speaker{
        public boolean speak();
    }

    class ZhangSan implements Speaker{
        public ZhangSan() {
        }

        @Override
        public boolean speak() {
            System.out.println("阐述事实");
            return true;
        }
    }

    class SpeakerProxy implements InvocationHandler{

        //目标对象
        private Object target = null;

        public void setObject(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = null;
            if(method.getName().equals("speak")){
                System.out.println("说话前");

                result = method.invoke(target, args);//反射
                System.out.println(result);

                System.out.println("说话后");
            }
            return result;
        }
    }
}

2、cglib动态代理


public interface UserService {
    public void save();
}

public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        System.out.println("吃饭");
    }
}

public class UserServiceCglibProxy {
    
    public static UserService createUserServiceCglibProxy(Class clazz){

        //创建动态的一个字节码对象
        Enhancer enhancer = new Enhancer();

        enhancer.setSuperclass(clazz);

        enhancer.setCallback(new MethodInterceptor() {
            /**
             *
             * @param o  被代理出来的类的对象
             * @param method  原始方法
             * @param args
             * @param methodProxy
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object result = methodProxy.invokeSuper(o, args);
                if(method.getName().equals("save")){
                    System.out.println("喝水");
                    System.out.println("睡觉");
                }
                return result;
            }
        });

        UserService t = (UserService enhancer.create();

        return t;
    }
}

class Test{
    public static void main(String[] args) {
        UserService userService = UserServiceCglibProxy.createUserServiceCglibProxy(UserServiceImpl.class);
        userService.save();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值