静态代理和动态代理

静态代理

由程序创建或者特定工具生成的源代码,在程序运行前,代理类的.class文件已经生成 通过将目标类与代理类实现同一个接口,让代理类持有真实类对 象,然后在代理类方法中调用真实类方法,在调用真实类方法的前 后添加我们所需要的功能扩展代码来达到增强的目的,一句话,自己手写代理类就是静态代理。
public interface ClothFactory {


    /**
     * 生产衣服
     */
    void produceCloth();
}

// 被代理类
public class NikeClothFactory implements ClothFactory{
    @Override
    public void produceCloth() {
        System.out.println("Nike开始生产衣服");
    }
}

public class ClothProxyFactory implements ClothFactory{



    // 创建代理类对象
    private ClothFactory clothFactory;


    public ClothProxyFactory(ClothFactory clothFactory){
        this.clothFactory = clothFactory;
    }


    /**
     * 对被代理类的方法进行拦截处理
     */
    @Override
    public void produceCloth() {

        System.out.println("服饰工厂开始准备");
        // 被代理类方法执行
        clothFactory.produceCloth();

        System.out.println("服饰工厂准备结束");
    }
}

public class StaticProxyTest {
    public static void main(String[] args) {

        // 被代理类
        NikeClothFactory nikeClothFactory = new NikeClothFactory();

        ClothProxyFactory clothProxyFactory = new ClothProxyFactory(nikeClothFactory);

        clothProxyFactory.produceCloth();
    }
}

动态代理

JDK动态代理,要求目标对象实现一个接口,但是有时候目标对象只是 一个单独的对象,并没有实现任何的接口,这个时候就可以用CGLib动 态代理 JDK动态代理使自带的,CGLib需要引入第三方包 CGLib动态代理,他是在内存中构建一个子类对象从而实现对目标对象 功能的扩展 CGLib动态代理基于继承来实现代理,所以无法对final类、private方法 和static方法实现代理

JDK动态代理

public interface Human {


    void breath();

    void eat(String food);
}

public class Student implements Human{


    @Override
    public void breath() {
        System.out.println("呼吸最新鲜的空气");
    }

    @Override
    public void eat(String food) {
        System.out.println("学生应该吃:"+food);
    }
}

public class JDKProxy implements InvocationHandler {

    // 创建被代理类对象
    private Object targetObj;

    // 返回被代理对象
    public Object newInstance(Object targetObj){
        this.targetObj = targetObj;
        return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("动态代理开始----------调用方法"+method.getName());

        Object result = method.invoke(targetObj,args);

        System.out.println("动态代理结束----------调用方法"+method.getName());

        return result;
    }
}

public class JDKProxyTest {

    public static void main(String[] args) {

        // 创建被代理类
        Student student = new Student();

        // JDK动态代理类
        JDKProxy jdkProxy = new JDKProxy();
        Human human = (Human) jdkProxy.newInstance(student);
        human.breath();
        human.eat("有营养的食物");

    }
}

CGLib动态代理

public interface Human {


    void breath();

    void eat(String food);
}

public class Student implements Human{


    @Override
    public void breath() {
        System.out.println("呼吸最新鲜的空气");
    }

    @Override
    public void eat(String food) {
        System.out.println("学生应该吃:"+food);
    }
}

public class CGLibProxy implements MethodInterceptor {

    // 代理类
    private Object targetObj;

    public Object newInstance(Object targetObj){
        this.targetObj = targetObj;

        // 创建CGLib代理类
        Enhancer enhancer = new Enhancer();

        // 设置代理类的⽗类(⽬标类)
        enhancer.setSuperclass(this.targetObj.getClass());
        // 设置代理类的⽗类(⽬标类)
        enhancer.setCallback(this);

        // 创建子类(代理对象)
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("CGLib动态代理开启-------调用方法"+method.getName());

        // 调用被代理类
        Object result = methodProxy.invokeSuper(o,objects);

        System.out.println("CGLib动态代理结束-------调用方法"+method.getName());
        return result;
    }
}

public class CGLibTest {

    public static void main(String[] args) {

        // 创建被代理类
        Student student = new Student();
        // 创建CGLib被代理类
        CGLibProxy cgLibProxy = new CGLibProxy();
        Student human = (Student) cgLibProxy.newInstance(student);
        human.breath();
        human.eat("有营养的食物");

    }
}

Spring AOP 底层原理

aop 底层是采用动态代理机制实现的:接口+实现类 如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象。 没有实现接口的对象,就无法使用JDK Proxy去进行代理了,这时候Spring AOP会使用Cglib生成一个被代理对象的子类来作为代理。 就是由代理创建出一个和impl实现类平级的一个对象,但是这个对象不是一个真正的对象,只是一个代理对象,但它可以实现和impl相同的功能,这个就是aop的横向机制原理,这样就不需要修改源代码。
posted @ 2022-06-26 16:16  DiligentCoder  阅读(110)  评论(0编辑  收藏  举报