1. Overview
1.概述
By design, classes annotated with @Repository, @Service, @Controller, etc. are managed by Spring and injecting configuration there is easy and natural. What’s not as simple is passing configuration to classes that are not directly managed by Spring.
根据设计,带有 @Repository、@Service、@Controller等注释的类由Spring管理,在那里注入配置是很容易和自然的。不那么简单的是将配置传递给不直接由Spring管理的类。
In that case, we can use ClassLoader-based configuration loading or simply instantiate our classes in another bean and set required params manually – this is the suggested option because configuration entries don’t need to be stored in *.properties files exclusively.
在这种情况下,我们可以使用基于ClassLoader-的配置加载,或者简单地在另一个Bean中实例化我们的类,并手动设置所需的参数–这是建议的选项,因为配置项不需要完全存储在*.properties文件中。
In this quick article, we are going to cover the topic of loading *.properties files with Java ClassLoader as well as injection of already loaded configuration by Spring into an unmanaged class.
在这篇文章中,我们将介绍用Java ClassLoader加载.properties文件,以及将已经由Spring 加载的配置注入到非托管类中的话题。
2. Load Configuration With Class Loader
2.用类加载器加载配置
Simply put, *.properties files are resources files holding some config info. Instead of using third party implementations that support automatic application configuration loading, e.g. that implemented in Spring, we can use Java ClassLoader to do the same.
简单地说,*.properties文件是保存一些配置信息的资源文件。我们可以使用Java ClassLoader来做同样的事情,而不是使用支持自动加载应用程序配置的第三方实现,例如Spring中实现的实现。
We’re going to create a container object that will hold Properties defined in resourceFileName. To fill up the container with configuration, we will use a ClassLoader.
我们将创建一个容器对象,它将容纳Properties中定义的resourceFileName。为了用配置填充容器,我们将使用一个ClassLoader。
Let’s define PropertiesLoader class that implements loadProperties(String resourceFileName) method:
让我们定义PropertiesLoader类,实现loadProperties(String resourceFileName)方法。
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;
}
}
Every Class object contains a reference to the ClassLoader that instantiated it; this is an object that is primarily responsible for loading classes, but in this tutorial, we’ll use it for loading resource file instead of plain Java class. The ClassLoader is looking for resourceFileName on the classpath.
每个Class对象都包含对实例化它的ClassLoader的引用;这是一个主要负责加载类的对象,但在本教程中,我们将用它来加载资源文件而不是普通的Java类。ClassLoader正在classpath上寻找resourceFileName。
Afterward, we load the resource file as InputStream via the getResourceAsStream API.
之后,我们通过getResourceAsStream API将资源文件加载为InputStream。
In the above example, we defined a configuration container that can parse resourceFileName using the load(InputStream) API.
在上面的例子中,我们定义了一个配置容器,可以使用load(InputStream) API解析resourceFileName。
The load method implements parsing of *.properties files with support of “:” or “=” characters as delimiters. Additionally, both “#” or “!” characters used at the beginning of the new line are comment markers and cause that line to be ignored.
加载方法实现了对*.properties文件的解析,支持“:”或“=”字符作为分隔符。此外,在新行开始时使用的“#”/em>或“!”/em>字符都是注释标记,导致该行被忽略。
Finally, let’s read the exact value of defined configuration entry from our configuration files:
最后,让我们从我们的配置文件中读取所定义的配置项的准确值。
String property = configuration.getProperty(key);
3. Loading Configuration With Spring
3.用Spring加载配置
A second solution is to make use of Spring Spring feature to handle some of the low-level loading and processing of files.
第二个解决方案是利用SpringSpring功能来处理一些低层次的文件加载和处理。
Let’s define an Initializer that will hold the configuration needed to initialize our custom class. During Bean initialization, the framework will load all of the fields annotated with @Value from *.properties config file:
让我们定义一个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);
}
}
The Initializer can now be responsible for instantiating the ClassNotManagedBySpring.
初始化器现在可以负责实例化ClassNotManagedBySpring。
Now we’ll simply access our Initializer instance and run the initClass() method on it to handle the instantiation of our custom ClassNotManagedBySpring:
现在我们将简单地访问我们的Initializer实例,并对其运行initClass()方法来处理我们的自定义ClassNotManagedBySpring的实例化。
ClassNotManagedBySpring classNotManagedBySpring = initializer.initClass();
Once we have the reference to Initializer, we’ll be able to instantiate our custom ClassNotManagedBySpring.
一旦我们有了对Initializer的引用,我们就可以将我们的自定义ClassNotManagedBySpring实例化。
4. Summary
4.总结
In this quick tutorial, we focused on reading properties into a non-Spring Java class.
在这个快速教程中,我们着重于将属性读入一个非Spring Java类。
As always, an example implementation can be found over on GitHub.
一如既往,可以在GitHub上找到实现的例子。