Spring AOP代理和接口实现

Spring AOP代理和接口实现,spring,proxy,spring-aop,Spring,Proxy,Spring Aop,我试图理解Spring代理机制,但有一点我有问题。 我有接口: public interface MyInterface{ void myMethod(); } 和实现类: @Component public class MyBean implements MyInterface{ @Override public void myMethod(){ //do something } } 现在我创建Aspect,例如: @Aspect @Component public

我试图理解Spring代理机制,但有一点我有问题。 我有接口:

public interface MyInterface{
  void myMethod();
}
和实现类:

@Component
public class MyBean implements MyInterface{
  @Override
  public void myMethod(){
    //do something
  }
}
现在我创建Aspect,例如:

@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();
    }
}
根据Spring文档,我们可以阅读:

如果要代理的目标对象实现了至少一个接口 然后将使用JDK动态代理。所有的接口 由目标类型实现的将被代理。如果目标对象 如果不实现任何接口,则将创建CGLIB代理

但是我得到一个错误,没有定义[MyBean]类型的限定bean。仅当我通过
@enableAspectProxy(proxyTargetClass=true)
启用CGLib代理时,它才起作用。
有人能解释一下我遗漏了什么吗?为什么在使用AOP时没有发现MyBean
ctx.getBean(MyInterface.class)
可以工作,但我无法想象这种接口的许多实现情况。

要代理的目标对象(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代理,因此不需要很多实现。

要代理的目标对象(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代理,因此不需要很多实现。

因为如果您检查bean类,您会找到com.sun.proxy。$Proxy21(或类似的东西),它包装了您的方法。它们是不兼容的类型,即使它们具有相同的接口。 例如:

public interface AnInterface {
   void func();
}

public class Bb implements AnInterface{
   @Override
   public void func() {
      System.out.println("bb");
   }
}

public class Cc implements AnInterface{
@Override
   public void func() {
      System.out.println("cc");
   }
}
所以当你打电话的时候

public static void main(String[] args) {
    Bb b = new Bb();
    Cc c=b; // Error
    AnInterface c=b; // Ok
}

因为如果你检查你的bean类,你会发现com.sun.proxy.$Proxy21(或类似的东西),它包装了你的方法。它们是不兼容的类型,即使它们具有相同的接口。 例如:

public interface AnInterface {
   void func();
}

public class Bb implements AnInterface{
   @Override
   public void func() {
      System.out.println("bb");
   }
}

public class Cc implements AnInterface{
@Override
   public void func() {
      System.out.println("cc");
   }
}
所以当你打电话的时候

public static void main(String[] args) {
    Bb b = new Bb();
    Cc c=b; // Error
    AnInterface c=b; // Ok
}