【发布时间】:2022-01-07 15:58:32
【问题描述】:
我尝试将ProxyFactoryBean 与@Autowired 一起使用,但它会在setInstrument 方法处引发异常。
问题 - 为什么它适用于以前称为 getBean 的方法或 @DependsOn?我试图了解 Spring 对这些额外步骤的执行情况。
提前谢谢你!
我有两个接口 - Singer 和 Instrument。以及它们的两个实现 - GuitarSinger.class 和 Guitar.class。
public interface Singer {
void singSong();
Instrument getInstrument();
}
@Service
@Lazy
public class GuitarSinger implements Singer {
private Instrument guitar;
@Autowired
public void setInstrument(Instrument instrument) {
this.guitar = instrument;
}
@Override
public Instrument getInstrument() {
return guitar;
}
@Override
public void singSong() {
System.out.println("I'm singing a song");
guitar.play();
}
}
public interface Instrument {
void play();
}
public class Guitar implements Instrument {
@Override
public void play() {
System.out.println("I'm a guitar!");
}
}
此接口用于代理介绍:
public interface GuitarChecker {
boolean isGuitarOk();
}
这个混入类实现了我们要引入代理的接口:
public class GuitarCheckerMixin extends DelegatingIntroductionInterceptor implements GuitarChecker {
@Override
public boolean isGuitarOk() {
System.out.println("I don't know how to check the guitar");
return true;
}
}
最终,带有main 方法的配置类:
@Configuration
@ComponentScan("com.annotation.test")
public class Config {
@Bean
public ProxyFactoryBean checkedGuitar() {
ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
Instrument guitar = new Guitar();
proxyFactoryBean.setTarget(guitar);
proxyFactoryBean.addAdvisor(new DefaultIntroductionAdvisor(new GuitarCheckerMixin()));
proxyFactoryBean.setProxyTargetClass(true);
return proxyFactoryBean;
}
public static void main(String[] args) {
AnnotationConfigApplicationContext appContext
= new AnnotationConfigApplicationContext(Config.class);
Singer singer = appContext.getBean(Singer.class);
singer.singSong();
Instrument instrument = singer.getInstrument();
GuitarChecker guitarChecker = (GuitarChecker) instrument;
guitarChecker.isGuitarOk();
}
}
如果我运行main,我会得到:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.annotation.test.Instrument' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:759)
... 17 more
但是如果我添加这两个步骤之一(只使用其中一个就可以),它将正常工作并打印结果。
-
将
@DependsOn("checkedGuitar")添加到GuitarSinger:@Service @Lazy @DependsOn("checkedGuitar") public class GuitarSinger implements Singer { -
在
main中再添加一行appContext.getBean("checkedGuitar")。public static void main(String[] args) { AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext(Config.class); appContext.getBean("checkedGuitar"); Singer singer = appContext.getBean(Singer.class); singer.singSong(); Instrument instrument = singer.getInstrument(); GuitarChecker guitarChecker = (GuitarChecker) instrument; guitarChecker.isGuitarOk(); }
通过这两个更新之一,应用程序将打印以下行:
I'm singing a song
I'm a guitar!
I don't know how to check the guitar
您能帮我理解这个问题吗?为什么它适用于@DependsOn 或getBean()?
【问题讨论】:
标签: java spring dependency-injection proxy spring-aop