动态代理(jdk和cglib)与静态代理---没有理解回调部分

基于动力节点视频做的笔记:

首先了解什么是代理

代理可以理解为中介:用户不能直接通过厂家购买少量的商品,只能通过淘宝等中间商购买,但是淘宝商家不是直接供货的,只是间接的供货—购买的事件最终是调用的目标方法是厂家提供的。

作用:1.目标方法的调用,2.方法的增强

静态代理

代理的目标明确,容易理解,但是目标方法多,编写繁琐,容易出错。
如果需要提供新的工厂接口方法,自己明确知道代理类中的方法。。

public interface SayHello {
    
    
    void say(String name);
    void print();
}

public class SayHelloImpl implements SayHello {
    
    

    @Override
    public void say(String name) {
    
    
        out.println(name);
    }

    @Override
    public void print() {
    
    

    }
}

package com.interview.proxytest;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author helloLi
 * @version 1.0
 * @date 2020/6/13 17:40
 *
 * 测试jdk中的反射机制(mothod代表目标方法)
 * 使用mothod方法(代表目标方法)进行调用invoke方法进行调用任意对象的的目标方法
 */
public class TestAop {
    
    
    public static void main(String[] args) throws Exception {
    
    
        // 通过反射机制执行sayhello方法 ,核心是mothod方法
        SayHello target = new SayHelloImpl();
        // 获取sayhello名称对于mothod的类的对象
        Method method = SayHello.class.getMethod("say", String.class);
        Method mothod2 = SayHello.class.getMethod("print",int.class);
        // 通过mothod可以执行sayhello方法调用
        //invoke是moethod类中的一个方法,表示执行调用 Oject表示对象的方法 Object...args 表示执行时候的参数
        SayHello target2 = new SayHelloImpl();
        Object lisi = method.invoke(target, "lisi");
        Object lisi2 = method.invoke(target2, "wangwu");
        mothod2.invoke(target, 1);

//        Proxy proxy = new Proxy();

    }
}


jdk动态代理(基于接口与反射)

代理的类是不明确的,需要传递参数确定代理类的信息,目标方法
实现invocationHandler接口

怎么用:
1.创建类实现接口invocationHandler;;
重写invoke()方法,,把原来的静态代理类完成的功能写在这

  1. mothod类:表示方法的,确切的说是目标类中的方法,作用:通过mothod可以执行某个目标类的方法:不需要知道执行的方法名
    Object lisi = method.invoke(target, “lisi”);
    Object lisi2 = method.invoke(target2, “wangwu”);
    等同于静态代理中的代理类调用目标类中的方法调用

  2. Proxy类:是核心,创建代理对象,之前是new 构造方法
    现在使用proxy中的方法来代替
    方法:静态方法:newProxyInstance();
    1.参数:classLaoder loader;类加载器,负责向内存中加载对象,使用反射获取对象的classLaoder类,a.getClass .getclassLoader() 目标对象的类加载器
    2.class<?>接口,目标对象实现的接口,也是反射获取

  3. invocationHandler h自己写的代理代理类需完成的功能

// 目标接口
public interface UsbSell {
    
    

    float sell(int amount);

    float buy(int amount);
    void print();
}

package com.interview.proxytest.auto;

/**
 * @author helloLi
 * @version 1.0
 * @date 2020/6/13 20:47
 */
// 目标类
public class UsbKingFactory implements UsbSell {
    
    
    @Override
    public float sell(int amount) {
    
    
        System.out.println("目标类中的目标方法");
        return 23;
    }

    @Override
    public float buy(int amount) {
    
    
        System.out.println("目标方法新增的购买方法");
        return 10;
    }

    @Override
    public void print() {
    
    
        //不影响代理类
    }
}

package com.interview.proxytest.auto;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @author helloLi
 * @version 1.0
 * @date 2020/6/13 20:48
 */
// 必须实现invocationHandler接口,完成代理类的功能(调用目标方法,功能增强)
public class MySellHandler implements InvocationHandler {
    
    

    private Object target = null;
    public MySellHandler(Object target) {
    
    
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        // 参考静态的代理类的
        Object res = null;
        // 动态的说明不固定,需要传入目标对象
        res = method.invoke(target,args);//执行目标方法
        //功能增强
        if(res != null){
    
    
            Float price = (Float)res;
            price = price + 25;
            res = price;
        }
        System.out.println("动态代理增强");
        return res;
    }
}

package com.interview.proxytest.auto;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * @author helloLi
 * @version 1.0
 * @date 2020/6/13 20:56
 */
public class MainShop {
    
    
    public static void main(String[] args) {
    
    
        // 创建目标对象
        UsbSell factory = new UsbKingFactory();
        // 创建invocationHandler对象
        InvocationHandler invocationHandler = new MySellHandler(factory);
        // 创建代理对象 不像静态的代理类的对象 事先知道目标调用方法名与参数
        UsbSell proxyInstance = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(), invocationHandler);
        // 通过动态代理执行目标方法--------底层实现的是invokeHandler对象中的invoker方法。
        float price = proxyInstance.buy(1);
        float buy = proxyInstance.sell(1);
        System.out.println("通过动态代理对象,调用:"+ price+" / "+ buy);
    }
}

Cglib可以实现不是基于接口的目标方法方法的代理

既可以基于接口也可以基于一般类

cglib代理类核心是子类增强父类,将目标方法所在类作为父类,在子类中增强。
回调方法是指达到一定的条件就会触发的方法

说是调用目标方法回触发回调没有理解

package com.interview.cglib.cglib2;

/**
 * @author helloLi
 * @version 1.0
 * @date 2020/6/14 11:56
 *
 * 基于cglib的代理,需要自己手工创建工厂
 */
// 目标类的方法,是没有实现接口
public class SellService {
    
    
    public String sell(){
    
    
        System.out.println("卖东西方法");
        return "helloWorld";
    }

    public String buy(){
    
    
        System.out.println("买东西方法");
        return "32块";
    }
}

package com.interview.cglib.cglib2;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.omg.CORBA.PUBLIC_MEMBER;

import java.lang.reflect.Method;

/**
 * @author helloLi
 * @version 1.0
 * @date 2020/6/14 12:00
 */
public class CglibFactory implements MethodInterceptor {
    
    

    private SellService target;

    public SellService myCglibSell(){
    
    
        // 增强
        Enhancer enhancer = new Enhancer();
        // 目标类设置为父类,基于cglib增强的特点:子类增强父类---指定目标类为父类
        enhancer.setSuperclass(SellService.class);
        //怎么增强--回头再调用,达到执行条件之后回头在调用,this表示当前的对象
        enhancer.setCallback(this);
        // create() 用于创建 cglib动态代理的对象
        return (SellService) enhancer.create();
    }

    public CglibFactory() {
    
    
    }

    public CglibFactory(SellService target) {
    
    
        this.target = target;
    }

    // 回调接口的方法:触发执行的条件--执行目标方法时候回触发该方法
    // 增强的原理是子类增强父类
    @Override
    public Object intercept(Object o, Method method,
                            Object[] objects, MethodProxy methodProxy) throws Throwable {
    
    
        Object invoke = method.invoke(target, objects);
        if (invoke != null){
    
    
            invoke = ((String)invoke).toUpperCase();
        }
        System.out.println("增强");
        invoke = invoke+"得了";
        return invoke;
    }
}

package com.interview.cglib.cglib2;

import com.interview.JSONUtil;
import org.w3c.dom.ls.LSOutput;

/**
 * @author helloLi
 * @version 1.0
 * @date 2020/6/14 12:51
 */
public class MyTest {
    
    
    public static void main(String[] args) {
    
    

        SellService target = new SellService();
        SellService sevice = new CglibFactory(target).myCglibSell();
        String result = sevice.buy();
        System.out.println(result);
        String sell = sevice.sell();
        System.out.println(sell);

    }
}


猜你喜欢

转载自blog.csdn.net/qq_42664961/article/details/106745982