spring ioc注入接口的具体实现来测试
我有以下设置:
@Component
public class ImplOne implements IFace{
}
@Component
public class ImplTwo implements IFace{
}
public interface IFace{
}
我试图按类型获取 ImplOne 的引用:
@RunWith(SpringJUnit4ClassRunner.class)
public class ImplOneTest {
@Autowired
private ImplOne impl;
@Test
public void test(){
Assert.assertNotNull(impl);
}
}
虽然这样我得到了以下异常:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [some.package.TestBean] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
我尝试了以下解决方法:
- 从 ImplOne 中删除“implements IFace”,以便实现类本身由 cglib 代理。不可接受,因为我还需要能够在我的应用程序代码中获取 IFace 的所有实现。
- 通过@Autowired public void setImplOne(IFace[] beans)进行方法注入并通过instanceof检查过滤实例是行不通的,因为注入的bean是java.lang.reflect.Proxy类型的子类,没有提供任何有用的方法。
- 将 ImplOne 的 @Component 更改为 @Component("implone") 并使用 @Qualifier("implone")。
代码:
@RunWith(SpringJUnit4ClassRunner.class)
public class ImplOneTest {
@Autowired
@Qualifier("implone")
private ImplOne impl;
@Test
public void test(){
Assert.assertNotNull(impl);
}
}
但我不喜欢必须命名我的 bean 才能注入具体实现的想法。
有没有办法优雅地做到这一点,或者至少以某种只影响我的测试代码的方式?还有一些特殊原因导致我的第一个示例不受支持吗?
I have the following setup:
@Component
public class ImplOne implements IFace{
}
@Component
public class ImplTwo implements IFace{
}
public interface IFace{
}
I am trying to get a reference of ImplOne by type:
@RunWith(SpringJUnit4ClassRunner.class)
public class ImplOneTest {
@Autowired
private ImplOne impl;
@Test
public void test(){
Assert.assertNotNull(impl);
}
}
Though with this I get the following exception:
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No matching bean of type [some.package.TestBean] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
I tried the following workarounds:
- Remove "implements IFace" from ImplOne so the implementation class itself gets Proxied by cglib. Not acceptable because I also need to be able to get all implementations of IFace in my application code.
- Doing method injection via a @Autowired public void setImplOne(IFace[] beans) and filtering the instance through instanceof check does not work, because the injected beans are subclasses of type java.lang.reflect.Proxy which doesn't offer any useful methods.
- Changing @Component of ImplOne to @Component("implone") and using @Qualifier("implone").
Code:
@RunWith(SpringJUnit4ClassRunner.class)
public class ImplOneTest {
@Autowired
@Qualifier("implone")
private ImplOne impl;
@Test
public void test(){
Assert.assertNotNull(impl);
}
}
But I don't like the idea of having to name my beans just to be able to inject the concrete implementation.
Is there some way to do this elegantly, or atleast in some manner that only affects my test code? Also is there some special reason why my first example is unsupported?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
@Autowired
+@Qualifier
或使用@Resource(name= "")
来注入你想要的东西。这并没有什么问题。@Autowired
+@Qualifier
, or use@Resource(name="")
to inject what you want. And there is nothing wrong with this.好吧,今天我终于找到了一种方法来完成这项工作。看来 Spring-AOP-Autoproxy 应该为这个不起作用负责。
目前,我在 Eclipse 中使用 AJDT 进行编译时编织 (CTW) 和 TransactionAnnotationAspect。我还删除了项目中的aspectjweaver和cglib依赖项,因此在从applicationcontext中删除以下配置部分后,甚至不再支持autoproxy:
这也是@Configurable对我不起作用的原因......
Ok, today i found a way to make this work afterall. Seems like the Spring-AOP-Autoproxy was to blame for this not to work.
Currently I am using AJDT in Eclipse for compile time weaving (CTW) and the TransactionAnnotationAspect. I also removed the aspectjweaver and cglib dependency in my project, so autoproxy is not even supported anymore, after removing the following config part from applicationcontext:
And that was also the reason why @Configurable didn't work for me...
添加以下行对我有用:
Adding the following line worked for me: