面试题:被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();
        }

    }

原文地址:https://www.cnblogs.com/crazymakercircle/p/15554561.html