Spring AOP代理和接口实现
我试图理解Spring代理机制,但有一点我有问题。 我有接口: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
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
}