Spring 配置注入非托管类
1. 概述
根据设计,使用*@Repository*、@Service、@Controller等注解的类由 Spring 管理,并且注入配置很容易和自然。不那么简单的是将配置传递给不由 Spring 直接管理的类。
在这种情况下,我们可以使用基于ClassLoader的配置加载或简单地在另一个 bean 中实例化我们的类并手动设置所需的参数——这是建议的选项,因为配置条目不需要专门存储在 *.properties 文件中。
在这篇快速文章中,我们将介绍使用 Java ClassLoader加载 *.properties 文件以及将Spring 已加载的配置 注入非托管类的主题。
2. 使用类加载器加载配置
简单地说, *.properties 文件是包含一些配置信息的资源文件。代替使用支持自动应用程序配置加载的第三方实现,例如在 Spring 中实现的,我们可以使用 Java ClassLoader来做同样的事情。
我们将创建一个容器对象,该对象将保存在resourceFileName中定义的Properties。为了用配置填充容器,我们将使用ClassLoader。
让我们定义实现loadProperties(String resourceFileName)方法的PropertiesLoader类:
public class PropertiesLoader {
public static Properties loadProperties(String resourceFileName) throws IOException {
Properties configuration = new Properties();
InputStream inputStream = PropertiesLoader.class
.getClassLoader()
.getResourceAsStream(resourceFileName);
configuration.load(inputStream);
inputStream.close();
return configuration;
}
}
每个Class对象都包含对实例化它的ClassLoader的引用;这是一个主要负责加载类的对象,但在本教程中,我们将使用它来加载资源文件而不是普通的 Java 类。ClassLoader正在类路径中查找resourceFileName。
之后,我们通过getResourceAsStream API将资源文件加载为InputStream。
在上面的示例中,我们定义了一个可以使用load(InputStream) API解析resourceFileName的配置容器。
load 方法实现对 *.properties 文件的解析,支持*“:”或“=”字符作为分隔符。此外,“#”或“!”* 新行开头使用的字符是注解标记,会导致该行被忽略。
最后,让我们从配置文件中读取已定义配置条目的确切值:
String property = configuration.getProperty(key);
3. 使用 Spring 加载配置
第二种解决方案是利用 Spring Spring 特性来处理文件的一些低级加载和处理。
让我们定义一个Initializer来保存初始化我们的自定义类所需的配置。在Bean初始化期间,框架将从 *.properties 配置文件中加载所有带有*@Value*注解的字段:
@Component
public class Initializer {
private String someInitialValue;
private String anotherManagedValue;
public Initializer(
@Value("someInitialValue") String someInitialValue,
@Value("anotherValue") String anotherManagedValue) {
this.someInitialValue = someInitialValue;
this.anotherManagedValue = anotherManagedValue;
}
public ClassNotManagedBySpring initClass() {
return new ClassNotManagedBySpring(
this.someInitialValue, this.anotherManagedValue);
}
}
Initializer现在可以负责实例化ClassNotManagedBySpring。
现在我们将简单地访问我们的Initializer实例并在其上运行initClass()方法来处理我们自定义ClassNotManagedBySpring的实例化:
ClassNotManagedBySpring classNotManagedBySpring = initializer.initClass();
一旦我们有了对Initializer的引用,我们就可以实例化我们的自定义ClassNotManagedBySpring。