Spring学习笔记——Spring怎么装配各种类型的属性以及实际应用
Spring学习笔记——Spring如何装配各种类型的属性以及实际应用
在类中的定义的属性我们可以通过Spring的容器给他们赋值,Spring这种功能在我们实际中有什么作用呢?举个我在工作中实际用的例子吧,
如果我们把数据库的连接配置文件加密了,我们就不能直接加载使用了,这时候我们需要先把配置文件进行解密,然后把解密之后的值赋给一个常量类,这时候我们通过加载这个常量类中的属性来完成数据库的连接。
代码如下:
<!-- 解密config.properties文件 -->
<bean id="myPropertyConfigurer" class="com.fyw.commons.security.DecryptPropertyPlaceholderConfigurer">
<property name="locations" value="classpath:config.properties"/>
<!--<list><value>classpath:config.properties</value></list>
</property> -->
<property name="fileEncoding" value="UTF-8"/>
<property name="keyLocation" value="classpath:key.key" />
</bean>
<!-- 常量属性-->
<bean id="Constant" class="com.fyw.common.Constant">
<property name="DEFAULT_SAVE_PATH" value="${file.defaultSavePath}" />
<property name="COMPARE_ACCOUNT_FILE_PATH" value="${file.compareAccountFilePath}" />
<property name="SHARE_PROFITS_FILE_PATH" value="${file.shareProfitsFilePath}" />
<property name="ENDECRYPT_PUBLIC_KEY" value="${file.publicKey}" />
<property name="EMAIL_FROM" value="${email.from}" />
<property name="EMAIL_TO_ERROR" value="${email.to.error}" />
<property name="EMAIL_TO_NORMAL" value="${email.to.normal}" />
<property name="ENV" value="${env}" />
</bean>
下面看看DecryptPropertyPlaceholderConfigurer
public class DecryptPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private Resource[] locations;
private Resource keyLocation;
private String fileEncoding;
public void setLocations(Resource[] locations){
try {
this.locations = locations;
} catch (Exception e) {
e.printStackTrace();
}
}
public void setKeyLocation(Resource keyLocation){
try {
this.keyLocation = keyLocation;
} catch (Exception e) {
e.printStackTrace();
}
}
public void setFileEncoding(String fileEncoding) {
this.fileEncoding = fileEncoding;
}
public void loadProperties(Properties props) throws IOException{
if (this.locations != null){
PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
for (int i = 0; i < this.locations.length; i++) {
Resource location = this.locations[i];
if (logger.isInfoEnabled()){
logger.info("Loading properties file from " + location);
}
InputStream is = null;
try{
is = location.getInputStream();
Key key =getKey(keyLocation.getInputStream());
is =doDecrypt(key, is);
if (fileEncoding != null){
propertiesPersister.load(props, new InputStreamReader(
is, fileEncoding));
}else{
propertiesPersister.load(props, is);
}
}
finally{
if (is != null){
is.close();
}
}
}
}
}
/**
* <ul>
* <li>Description:[根据流得到密钥]</li>
* <li>Midified by [修改人] [修改时间]</li>
*/
public static Key getKey(InputStream is){
try{
ObjectInputStream ois = new ObjectInputStream(is);
return (Key) ois.readObject();
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* <ul>
* <li>Description:[对数据进行解密]</li>
* </ul>
* @param key
* @param in
* @return
*/
public static InputStream doDecrypt(Key key, InputStream in){
try{
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
byte[] tmpbuf = new byte[1024];
int count = 0;
while ((count = in.read(tmpbuf)) != -1){
bout.write(tmpbuf, 0, count);
tmpbuf = new byte[1024];
}
in.close();
byte[] orgData = bout.toByteArray();
byte[] raw = cipher.doFinal(orgData);
ByteArrayInputStream bin = new ByteArrayInputStream(raw);
return bin;
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
完成以上操作我们就可以直接使用Constant类中的常量了。
以上是对普通的字段通过SpringIOC进行装配,如果是其他类型的呢?下面我说说Set、List、Map、Properties这几种类型的赋值方法:
配置文件如下:
<bean id="personService" class="com.fyw.service.impl.PersonServiceBean">
<property name="sets">
<set>
<value>第一个</value>
<value>第二个</value>
<value>第三个</value>
</set>
</property>
<property name="lists">
<list>
<value>第一个list元素</value>
<value>第二个list元素</value>
<value>第三个list元素</value>
</list>
</property>
<property name="properties">
<props>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
<prop key="key3">value3</prop>
</props>
</property>
<property name="maps">
<map>
<entry key="key-1" value="value-1"/>
<entry key="key-2" value="value-2"/>
<entry key="key-3" value="value-3"/>
</map>
</property>
</bean>
PersonService类的代码很简单,如下:
public class PersonServiceBean implements PersonService {
private Set<String> sets = new HashSet<String>();
private List<String> lists = new ArrayList<String>();
private Properties properties = new Properties();
private Map<String, String> maps = new HashMap<String, String>();
public Map<String, String> getMaps() {
return maps;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Set<String> getSets() {
return sets;
}
public void setSets(Set<String> sets) {
this.sets = sets;
}
public List<String> getLists() {
return lists;
}
public void setLists(List<String> lists) {
this.lists = lists;
}
public void save(){
}
}
测试代码如下:
@Test public void instanceSpring(){
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService)ctx.getBean("personService");
System.out.println("========set===========");
for(String value : personService.getSets()){
System.out.println(value);
}
System.out.println("========list===========");
for(String value : personService.getLists()){
System.out.println(value);
}
System.out.println("========properties===========");
for(Object key : personService.getProperties().keySet()){
System.out.println(key+"="+ personService.getProperties().getProperty((String)key));
}
System.out.println("========map===========");
for(String key : personService.getMaps().keySet()){
System.out.println(key+"="+ personService.getMaps().get(key));
}
ctx.close();
}