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();
            }
    
        }
    
    
  • 相关阅读:
    java Activiti 工作流引擎 SSM 框架模块设计方案
    自定义表单 Flowable 工作流 Springboot vue.js 前后分离 跨域 有代码生成器
    数据库设计的十个最佳实践
    activiti 汉化 stencilset.json 文件内容
    JAVA oa 办公系统模块 设计方案
    java 考试系统 在线学习 视频直播 人脸识别 springboot框架 前后分离 PC和手机端
    集成 nacos注册中心配置使用
    “感恩节 ”怼记
    仓颉编程语言的一点期望
    关于System.out.println()与System.out.print("\n")的区别
  • 原文地址:https://www.cnblogs.com/crazymakercircle/p/15554561.html
Copyright © 2011-2022 走看看