我有实现MyInterface的类,例如:
MyClassA
,MyClassB
等。
如何通过它的bean名称获取类的实例?类似的东西:
context.getBean("myClassA")
context.getBean("myClassB")
如果不在XML中配置bean,我可以这样做吗? 我想使用注释
答案 0 :(得分:1)
您可以使用qualifiers,例如:
@Component
@Qualifier("classA")
public MyInterface ClassA {
return new ClassA();
}
@Component
@Qualifier("classB")
public MyInterface ClassB {
return new ClassB();
}
并使用它:
public class SomeClass {
@Autowired
@Qualifier("classA")
private MyInterface classA;
}
答案 1 :(得分:0)
这里有几个选项。最简单的方法是使用@Autowire
@Component("testClassA") // It is possible to omit explicit bean name declaration here since Spring will use a class name starting from lower case letter as a bean name by default. So just `@Component` should be sufficient here and below.
public TestClassA implements MyInterface {
}
@Component("testClassB")
public TestClassB implements MyInterface {
}
/*
* Note that field names are the same as the component names.
*/
@Component
public class TestClassWithDependencies {
@Autowired
private MyInterface testClassA;
@Autowired
private MyInterface testClassB;
}
另一种选择是使用qualifiers:
@Component
@Qualifier("testClassA")
public TestClassA implements MyInterface {
}
@Component
@Qualifier("testClassB")
public TestClassB implements MyInterface {
}
@Component
public class TestClassWithDependencies {
@Autowired
@Qualifier("testClassA")
private MyInterface testClassA;
@Autowired
@Qualifier("testClassB")
private MyInterface testClassB;
}
当您需要反复使用相同的限定符时,您甚至可以创建自己的元注释:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("testClassA")
public @interface TestClassACustomQualifier {
String value();
}
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("testClassB")
public @interface TestClassBCustomQualifier {
String value();
}
@Component
public class TestClassWithDependencies {
@Autowired
@TestClassACustomQualifier
private MyInterface testClassA;
@Autowired
@TestClassBCustomQualifier
private MyInterface testClassB;
}
更漂亮,不是吗?还有一个选择是使用JSR-250规范中的 @Resource 。正如@hovanessyan所指出的那样,JavaEE的做事风格更多,但我认为这是一种在许多项目中使用的可行方法:
@Component("testClassA")
public TestClassA implements MyInterface {
}
@Component("testClassB")
public TestClassB implements MyInterface {
}
@Component
public class TestClassWithDependencies {
@Resource(name="testClassA")
private MyInterface testClassA;
@Resource(name="testClassB")
private MyInterface testClassB;
}
您可以了解更多信息https://www.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/,其中讨论了添加测试的不同方法。
希望这有帮助!
答案 2 :(得分:0)
我认为如果以上选项不够,那么factory implementation
是获取实例的一种方法 -
@Component
public TestClassA implements MyInterface {
}
@Component
public TestClassB implements MyInterface {
}
以这种方式定义工厂 -
public class MyInterfaceFactory extends AbstractFactoryBean<MyInterface> {
private String filter;
@Override
public Class<?> getObjectType() {
return MyInterface.class;
}
@Override
protected MyInterface createInstance() throws Exception {
MyInterface myInterface;
switch (filter)
{
case "1":
myInterface = new TestClassA();
break;
case "2":
myInterface = new TestClassB();
break;
default: throw new IllegalArgumentException("No such type.");
}
return myInterface;
}
}
and then your bean config -
@Configuration
public class FactoryBeanConfig {
@Bean(name = "myInterface")
public MyInterfaceFactory myInterfaceFactory() {
MyInterfaceFactory factory = new MyInterfaceFactory();
factory.setFilter("7070");
return factory;
}
}