• 静态代理和动态代理


    静态代理

    由程序创建或者特定工具生成的源代码,在程序运行前,代理类的.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的横向机制原理,这样就不需要修改源代码。
  • 相关阅读:
    类和对象
    类和对象1
    常见的子串问题
    常见的算法问题全排列
    第六届蓝桥杯java b组第五题
    第六届蓝桥杯java b组第四题
    第六届蓝桥杯java b组第三题
    第六届蓝桥杯java b组第二题
    第六届蓝桥杯java b组第一题
    第八届蓝桥杯java b组第三题
  • 原文地址:https://www.cnblogs.com/LoveShare/p/16413723.html
Copyright © 2020-2023  润新知