我们如何在Spring上下文中创建bean以注入依赖项?
我可以通过指定MainFactory
来创建factory-method = "newInstance"
,但是对于创建的实例,例如FirstCSVConcrete()
或FirstXLSConcrete()
。我还需要注入TotalReport
bean。那么,我们如何在Spring上下文中创建工厂时注入外部依赖项。
我要求使用Spring DI表示以下代码段并为MainFactory
和TotalReport
创建bean。另外,我不想将TotalReport
传递给newInstance()
方法。
public class MainFactory {
private FirstInterface firstInterface;
private MainFactory(String type){
if(type.equalsIgnoreCase("CSV")){
firstInterface = new FirstCSVConcrete();
} else {
firstInterface = new FirstXLSConcrete();
}
}
public static MainFactory newInstance(String type){
return new MainFactory(type);
}
}
public class FirstCSVConcrete implements FirstInterface {
TotalReport totalReport;
}
public class FirstXLSConcrete implements FirstInterface {
TotalReport totalReport;
}
答案 0 :(得分:0)
解决方案1
通常实例化FirstCSVConcrete
和FirstXLSConcrete
类型的bean,即:
@Component
public class FirstCSVConcrete implements FirstInterface {
@Autowired
private TotalReport totalReport;
}
同样适用于FirstXLSConcrete
。
现在,按如下方式设置MainFactory
:
public class MainFactory {
@Autowired
private FirstCSVConcrete firstCSVConcrete;
@Autowired
private FirstXLSConcrete firstXLSConcrete;
private String type;
public static MainFactory newInstance(String type){
return new MainFactory(type);
}
private MainFactory(String type) {
this.type = type;
}
private FirstInterface selectedFirstInterface = null;
public FirstInterface getFirstInterface() {
if(selectedFirstInterface == null) {
selectedFirstInterface = selectFirstInterfaceForType(type);
}
return selectedFirstInterface;
}
private FirstInterface selectFirstInterfaceForType(String type) {
if("CSV".equalsIgnoreCase(type)) {
return firstCSVConcrete;
}
return firstXLSConcrete;
}
}
Spring
无法将依赖项注入您自己实例化的对象中。所以,你必须采用这种方法,或者其中的一种方法。
解决方案2:更加整洁;使用带有Spring的aspectj
@Component
public class TotalReport {
...
}
@Configurable
public class FirstXLSConcrete implements FirstInterface {
@Autowired
private TotalReport totalReport;
...
}
@Configurable
public class FirstCSVConcrete implements FirstInterface {
@Autowired
private TotalReport totalReport;
}
public class MainFactory {
private FirstInterface firstInterface;
private MainFactory(String type) {
if (type.equalsIgnoreCase("CSV")) {
firstInterface = new FirstCSVConcrete();
} else {
firstInterface = new FirstXLSConcrete();
}
System.out.println(firstInterface.getTotalReport());
}
public static MainFactory newInstance(String type) {
return new MainFactory(type);
}
}
在您的应用程序上下文配置文件中声明以下内容:
<context:load-time-weaver />
<context:spring-configured />
在应用程序的context.xml
目录中创建META-INF
,并将以下内容放入其中。
<Context path="/youWebAppName">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
useSystemClassLoaderAsParent="false"/>
</Context>
将Spring的spring-tomcat-weaver.jar
(可能名为org.springframework.instrument.tomcat-<version>.jar
)放在tomcat安装的lib
目录中,瞧,aspectj magic开始工作。对于使用@Configurable注释进行注释的类,@Autowired
依赖项将自动解析;即使实例是在弹簧容器外创建的。
我猜答案已经变得很长了。如果您想了解更多详情,请点击using aspectj with Spring链接。还有几个配置选项。把自己弄出来。