2016-09-20 80 views
0

我想了解Spring代理機制,我有一件事情的問題。 我有接口:春天AOP代理和接口實現

public interface MyInterface{ 
    void myMethod(); 
} 

和實現類:

@Component 
public class MyBean implements MyInterface{ 
    @Override 
    public void myMethod(){ 
    //do something 
    } 
} 

現在我創造方面,例如:

@Aspect 
@Component 
public class LogAspect { 
    @Before("execution(public * *(..))") 
    public void logBefore() { 
     System.out.println("Before aspect"); 
    } 
} 

而且我有簡單的入門級:

@Configuration 
@ComponentScan 
@EnableAspectJAutoProxy 
public class SpringAopApplication { 
    public static void main(String[] args) { 
     AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
       SpringAopApplication.class); 

     MyBean bean = ctx.getBean(MyBean.class); 
//  MyInterface bean = ctx.getBean(MyInterface.class); //works 
     bean.myMethod(); 

     ctx.close(); 
    } 
} 

A根據Spring文檔,我們可以閱讀:

如果要代理的目標對象實現至少一個接口 那麼將使用JDK動態代理。所有由目標類型實現的接口 將被代理。如果目標對象 未實現任何接口,則將創建CGLIB代理。

但我得到了一個錯誤類型[爲myBean]定義沒有合格豆。它只有當我啓用CGLib代理@EnableAspectJAutoProxy(proxyTargetClass = true)時纔有效。 有人可以解釋我在這裏失蹤了嗎?爲什麼在使用AOP時未發現MyBean? ctx.getBean(MyInterface.class)的作品,但我無法想象這種接口的許多實現的情況。

回答

2

要代理的目標對象(MyBean)實現至少一個接口(MyInterface),因此使用JDK代理。 該代理實現MyInterface,但不是MyBean的實例。 這就是爲什麼

MyInterface bean = ctx.getBean(MyInterface.class); 

作品和

MyBean bean = ctx.getBean(MyBean.class); 

沒有。

CGLib代理是通過創建目標對象的子類創建的,因此創建的bean是MyBean的子類並實現了MyInterface。 在這種情況下也

MyBean bean = ctx.getBean(MyBean.class); 

的作品。

...但我無法想象這種接口的許多實現情況。

MyInterface的唯一原因可能是,爲了讓spring能夠創建一個JDK代理,所以不需要有很多的實現。