文章很長,而且持續更新,建議收藏起來,慢慢讀!瘋狂創客圈總目錄 博客園版 為您奉上珍貴的學習資源 :
免費贈送 :《尼恩Java面試寶典》 持續更新+ 史上最全 + 面試必備 2000頁+ 面試必備 + 大廠必備 +漲薪必備
免費贈送 經典圖書:《Java高並發核心編程(卷1)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高並發核心編程(卷2)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《Java高並發核心編程(卷3)加強版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 經典圖書:《尼恩Java面試寶典 最新版》 面試必備 + 大廠必備 +漲薪必備 加尼恩免費領
免費贈送 資源寶庫: Java 必備 百度網盤資源大合集 價值>10000元 加尼恩領取
面試題:被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();
}
}