zoukankan      html  css  js  c++  java
  • 面试题:被final修饰的类可以被spring代理吗?

    面试题:被final修饰的类可以被spring代理吗?

    来自社群的两个面试题,其实也是两个基础的 面试题,大家一定要掌握

    社群问题:

    在这里插入图片描述

    结论

    场景1:

    如果委托类没有实现接口的话,就不能使用newProxyInstance方法,进而不能使用JDK动态代理

    场景2:

    Cglib是针对类来实现代理的,对指定的目标类生成一个子类,通过方法拦截技术拦截所有父类方法的调用。因为是生成子类,所以就不能用在final修饰的类上。

    综合起来,就是 被final修饰的类 ,不可以被spring代理

    参考代码:

    
        public interface Foo {
            void bar();
        }
    
    
        public class FooInvocationHandler implements InvocationHandler {
            Object target = null;
    
            public FooInvocationHandler(Object target) {
                this.target = target;
            }
    
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("method :" + method.getName() + " is invoked!");
                return method.invoke(target, args); // 执行相应的目标方法
            }
        }
    
    
        /**
         * 动态代理测试
         */
        @Test
        public void simpleDynamicProxyTest() {
            try {
                // 这里有两种写法,采用复杂的一种写法,有助于理解。
                Class<?> proxyClass = Proxy.getProxyClass(FooInvocationHandler.class.getClassLoader(), Foo.class);
                final Constructor<?> cons;
    
                cons = proxyClass.getConstructor(InvocationHandler.class);
    
                final InvocationHandler ih = new FooInvocationHandler(new Foo() {
                    @Override
                    public void bar() {
                        System.out.println("匿名的 br is invoked!");
                    }
                });
                Foo foo = (Foo) cons.newInstance(ih);
                foo.bar();
    
                // 下面是简单的一种写法,本质上和上面是一样的
            /*
            HelloWorld helloWorld=(HelloWorld)Proxy.
                     newProxyInstance(JDKProxyTest.class.getClassLoader(),
                            new Class<?>[]{HelloWorld.class},
                            new MyInvocationHandler(new HelloworldImpl()));
            helloWorld.sayHello();
            */
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
        /**
         * 动态代理测试
         */
        @Test
        public void simpleDynamicProxyTest2() {
            try {
                FooInvocationHandler handler = new FooInvocationHandler(new Foo() {
                    @Override
                    public void bar() {
                        System.out.println("匿名的 br is invoked!");
                    }
                });
                // 这里有两种写法,采用复杂的一种简单写法,对比上面的写法,有助于理解。
                Foo foo = (Foo) Proxy.newProxyInstance(FooInvocationHandler.class.getClassLoader(),
                        new Class<?>[]{Foo.class}, handler);
                foo.bar();
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        // 面试题:被final修饰的类可以被spring代理吗?
    
        public final class FinalFoo {
            void bar(){
                System.out.println("final class FinalFoo 的 bar 方法 is invoked!");
            }
        }
        
        public class FinalFooInvocationHandler implements InvocationHandler {
            FinalFoo target = null;
    
            public FinalFooInvocationHandler(FinalFoo target) {
                this.target = target;
            }
    
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("method :" + method.getName() + " is invoked!");
                return method.invoke(target, args); // 执行相应的目标方法
            }
        }
    
        /**
         * 动态代理测试
         */
        @Test
        public void simpleDynamicProxyTest3() {
            try {
                FinalFooInvocationHandler handler = new FinalFooInvocationHandler(new FinalFoo());
                // 面试题:被final修饰的类可以被spring代理吗?
                FinalFoo foo = (FinalFoo) Proxy.newProxyInstance(FooInvocationHandler.class.getClassLoader(),
                        new Class<?>[]{FinalFoo.class}, handler);
                foo.bar();
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
    
  • 相关阅读:
    jQuery入门教程
    vue-lazyload 图片不更新
    Eggjs 设置跨域请求
    Vue.js错误: Maximum call stack size exceeded
    ubuntu nginx ssl 证书配置
    ubuntu 安装nginx, 出现 Unable to locate package
    nginx 判断移动端或者PC端 进入不同域名
    node.js 生成二维码
    Linux 配置ssh 免密码登录
    nodejs 从部署到域名访问
  • 原文地址:https://www.cnblogs.com/crazymakercircle/p/15554561.html
Copyright © 2011-2022 走看看