Java 非常重(它们占用大量内存),我只能加载它们一次(因此,我会缓存它们)。谢谢,我读了一些关于DI概念的文章,但我还没有使用它。但是,我确实有一些问题:I)我认为可以配置这些bean,以便将参数传递给类的ctor,对吗?;ii)我的“应用程序上下文”(系统使用
Java 非常重(它们占用大量内存),我只能加载它们一次(因此,我会缓存它们)。谢谢,我读了一些关于DI概念的文章,但我还没有使用它。但是,我确实有一些问题:I)我认为可以配置这些bean,以便将参数传递给类的ctor,对吗?;ii)我的“应用程序上下文”(系统使用,java,design-patterns,oop,architecture,dependency-injection,Java,Design Patterns,Oop,Architecture,Dependency Injection,非常重(它们占用大量内存),我只能加载它们一次(因此,我会缓存它们)。谢谢,我读了一些关于DI概念的文章,但我还没有使用它。但是,我确实有一些问题:I)我认为可以配置这些bean,以便将参数传递给类的ctor,对吗?;ii)我的“应用程序上下文”(系统使用的语言)可以在运行时更改,我想知道是否可以使用DI进行更改;iii)通过缓存,您的意思是如果我调用englishContext.getBean(“解析器”)两次,那么第二次调用总是返回缓存版本?;iv)是否可以只使用Spring的IoC容器而不
非常重(它们占用大量内存),我只能加载它们一次(因此,我会缓存它们)。谢谢,我读了一些关于DI概念的文章,但我还没有使用它。但是,我确实有一些问题:I)我认为可以配置这些bean,以便将参数传递给类的ctor,对吗?;ii)我的“应用程序上下文”(系统使用的语言)可以在运行时更改,我想知道是否可以使用DI进行更改;iii)通过缓存,您的意思是如果我调用englishContext.getBean(“解析器”)两次,那么第二次调用总是返回缓存版本?;iv)是否可以只使用Spring的IoC容器而不是整个框架?1)我不确定“将参数传递给创建者”是什么意思。您可以在上下文中为bean本身指定属性(或构造函数参数)。2) 如果您使用的是每种语言的上下文,那么您将拥有一组ApplicationContext实例,并且您将从适当的实例中获得一个bean(例如解析器)。如果您需要,可以在运行时轻松地重新加载上下文本身。3) 默认情况下,是的。但如果这不是您想要的,您可以更改bean范围以始终返回一个新实例。4) 当然可以。您只能选择所需的模块(和JAR)。是的,我指的是构造函数参数,谢谢。我想我一定要试试迪。最后的问题:您通常将ApplicationContext存储在哪里(在代码中),并调用.getBean()方法?您是否有某种帮助器类来处理它们?另外,假设我有一个类
a
,它创建了类B
,它创建了类C
,而类C
需要一个标记器。在这种情况下,要使用DI,我是否需要更改A
、B
和C
的构造函数,以标记器作为参数,然后将其注入A
以使其进入其他类?Doh!ctor=构造函数。不知道我在想什么:-)我将更新我的答案,以显示处理上下文的示例模式,注释不是代码的地方。就A/B/C类而言,这完全取决于您想使用DI走多远——您当然可以在应用程序中注入几乎所有内容,但这在您的环境中可能是理想的,也可能不是理想的。构造函数注入虽然可能,但比只有setXXX()方法的属性注入要困难一些。我会在我的回答中展示一个例子。谢谢,我读了一些关于DI概念的文章,但我还没有使用它。但是,我确实有一些问题:I)我认为可以配置这些bean,以便将参数传递给类的ctor,对吗?;ii)我的“应用程序上下文”(系统使用的语言)可以在运行时更改,我想知道是否可以使用DI进行更改;iii)通过缓存,您的意思是如果我调用englishContext.getBean(“解析器”)两次,那么第二次调用总是返回缓存版本?;iv)是否可以只使用Spring的IoC容器而不是整个框架?1)我不确定“将参数传递给创建者”是什么意思。您可以在上下文中为bean本身指定属性(或构造函数参数)。2) 如果您使用的是每种语言的上下文,那么您将拥有一组ApplicationContext实例,并且您将从适当的实例中获得一个bean(例如解析器)。如果您需要,可以在运行时轻松地重新加载上下文本身。3) 默认情况下,是的。但如果这不是您想要的,您可以更改bean范围以始终返回一个新实例。4) 当然可以。您只能选择所需的模块(和JAR)。是的,我指的是构造函数参数,谢谢。我想我一定要试试迪。最后的问题:您通常将ApplicationContext存储在哪里(在代码中),并调用.getBean()方法?您是否有某种帮助器类来处理它们?另外,假设我有一个类a
,它创建了类B
,它创建了类C
,而类C
需要一个标记器。在这种情况下,要使用DI,我是否需要更改A
、B
和C
的构造函数,以标记器作为参数,然后将其注入A
以使其进入其他类?Doh!ctor=构造函数。不知道我在想什么:-)我将更新我的答案,以显示处理上下文的示例模式,注释不是代码的地方。就A/B/C类而言,这完全取决于您想使用DI走多远——您当然可以在应用程序中注入几乎所有内容,但这在您的环境中可能是理想的,也可能不是理想的。构造函数注入虽然可能,但比只有setXXX()方法的属性注入要困难一些。我也会在我的回答中展示一个例子。
public interface Tokenizer {
List<String> tokenize(String s);
}
public class EnglishTokenizer implements Tokenizer {
List<String> tokenize(String s) { ... };
}
public interface ChineseTokenizer implements Tokenizer {
List<String> tokenize(String s) { ... };
}
public enum TokenizerFactory {
SINGLETON;
private Map<Language, Tokenizer> cache;
public getTokenizer(Language) {
return cache.get(Language);
}
}
public class Language {
public Language(LanguageEnum) {/* load language specific components*/};
public Tokenizer getTokenizer() {/* language specific tokenizer */};
public Parser getParser() {/* language specific parser */};
}
# English context: english.xml
<bean id="Tokenizer" class="EnglishTokenizer"/>
<bean id="Parser" class="EnglishParser"/>
...
# Your code
ApplicationContext englishContext = ...; // context itself is injected
Parser englishParser = (Parser) englishContext.getBean("Parser");
public abstract class ComponentLocator {
protected static ComponentLocator myInstance;
protected abstract <T> T locateComponent(Class<T> componentClass, String language);
public static <T> T getComponent(Class<T> componentClass, String language) {
return myInstance.locateComponent(componentClass, language);
}
}
public class ComponentLocatorImpl extends ComponentLocator
implements ApplicationContextAware {
private ApplicationContext myApplicationContext;
public void setApplicationContext(ApplicationContext context) {
myApplicationContext = context;
myInstance = this;
}
@Override
protected <T> T locateComponent(Class<T> componentClass, String language) {
String beanName = componentClass.getName() + ":" + language;
return componentClass.cast(myApplicationContext.getBean(beanName, componentClass));
}
}
ApplicationContext ctx = new ClasspathXmlApplicationContext("components.xml");
Parser englishParser = ComponentLocator.getComponent(Parser.class, "English");
Parser chineseParser = ComponentLocator.getComponent(Parser.class, "Chinese");
<bean id="A" class="Aimpl">
<property name="B" ref="B"/>
</bean>
<bean id="B" class="Bimpl">
<property name="C" ref="C"/>
</bean>
<bean id="C" class="Cimpl">
<property name="tokenizer" ref="Tokenizer:English"/>
</bean>