我们经常可以在框架中看到配置文件中配置一些信息,然后就被自动注入到实体中,我们可以先简单实现一个对象属性注入的demo。
技术点:IO读写,反射
1、先构建一个最简单的maven项目,如图
2、Maven依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.9</version>
</dependency>
3、定义一个实体
import lombok.Data;
import java.io.*;
@Data
public class DBEntity {
private String driverName;
private String url;
private String userName;
private String passWord;
private String poolName;
/**
* 空闲池,最小连接数
*/
private int minFreeConnections;
/**
* 空闲池,最大连接数
*/
private int maxFreeConnections;
/**
* 初始连接数
*/
private int initFreeConnections;
/**
* 重试获得连接的频率 毫秒
*/
private long retryConnectionTimeOut;
/**
* 最大允许的连接数
*/
private int maxConnections;
/**
* 连接超时时间
*/
private long connectionTimeOut;
}
4、实现注入工具类
package com.xyj;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.xyj.entity.DBEntity;
import java.io.*;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* 读取文件注入对象中
*/
public class FileUtil {
private Map<String, String> getConfigMap(String fileName) throws IOException {
int count = 0;
Map<String, String> configMap = new HashMap<>();
InputStream is = this.getClass().getResourceAsStream("/"+fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = br.readLine()) != null) {
count++;
if (line.startsWith("#")) {
continue;
}
String lineWithoutSpace = line.replaceAll(" ", "");
if (StrUtil.isBlankIfStr(lineWithoutSpace)) {
continue;
}
String[] contentLine = lineWithoutSpace.split("=");
if (contentLine.length != 2) {
System.err.println(StrUtil.format("第{}行:{}不符合规则", count, line));;
continue;
}
String key = contentLine[0];
String value = contentLine[1];
configMap.put(key, value);
}
return configMap;
}
public static void main(String[] args) throws IOException {
FileUtil test = new FileUtil();
DBEntity dbEntity = test.readFile2Entity();
System.out.println(dbEntity);
}
public DBEntity readFile2Entity() {
String fileName = "application.properties";
return readFile2Entity(fileName);
}
public DBEntity readFile2Entity(String fileName) {
try {
Map<String, String> configMap = getConfigMap(fileName);
return initDBEntity(configMap);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private DBEntity initDBEntity(Map<String, String> configMap) {
if (MapUtil.isEmpty(configMap)) {
return new DBEntity();
}
DBEntity dbEntity = new DBEntity();
Field[] declaredFields = dbEntity.getClass().getDeclaredFields();
for (Field field : declaredFields) {
String fieldName = field.getName();
String fieldValue = configMap.get(fieldName);
if (fieldValue != null) {
try {
field.setAccessible(true);
if (field.getType().equals(String.class)) {
field.set(dbEntity, fieldValue);
} else if (field.getType().equals(Integer.class)||field.getType().equals(int.class)) {
field.set(dbEntity, Integer.parseInt(fieldValue));
} else if (field.getType().equals(Float.class)||field.getType().equals(float.class)) {
field.set(dbEntity, Float.parseFloat(fieldValue));
} else if (field.getType().equals(Double.class)||field.getType().equals(double.class)) {
field.set(dbEntity, Double.parseDouble(fieldValue));
} else if (field.getType().equals(BigDecimal.class)) {
field.set(dbEntity, new BigDecimal(fieldValue));
} else if (field.getType().equals(Boolean.class) || field.getType().equals(boolean.class)) {
field.set(dbEntity, Boolean.valueOf(fieldValue));
} else if (field.getType().equals(Character.class)||field.getType().equals(char.class)) {
field.set(dbEntity, fieldValue.charAt(0));
} else if (field.getType().equals(Byte.class)||field.getType().equals(byte.class)) {
field.set(dbEntity, Byte.decode(fieldValue));
} else if (field.getType().equals(Short.class)||field.getType().equals(short.class)) {
field.set(dbEntity, Short.valueOf(fieldValue));
} else if (field.getType().equals(Long.class)||field.getType().equals(long.class)) {
field.set(dbEntity, Long.valueOf(fieldValue));
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
return dbEntity;
}
}
5、配置文件
##驱动名称:不推荐com.mysql.jdbc.Driver,而是推荐使用com.mysql.cj.jdbc.Driver
driverName = com.mysql.cj.jdbc.Driver
##数据库连接地址
url = jdbc:mysql://127.0.0.1:3306/test
userName = root
passWord = root
##连接池名字
poolName = Hutao Connection Pool
##空闲池,最小连接数
minFreeConnections = 1
##初始化空闲池连接数
initFreeConnections = 3
##空闲池,最大连接数
maxFreeConnections = 5
#最大允许的连接数,一般小于数据库总连接数
maxConnections = 15
##重试获得连接的频率 一秒
retryConnectionTimeOut = 1000
##连接超时时间,默认20分钟 1000 * 60 * 20
connectionTimeOut = 1200000
6、运行main方法,输出结果如下
成功。
7、更多
这只是一个最简单的demo,我们还可以通过注解的方式,扫描整个项目(或者目标路径),遍历所有的属性,如果属性上存在我们自定义的注解,则对其进行赋值。这样就完成了项目的配置。
当然我们没有解决对象中含有对象属性的注入,也没有解决循环依赖的问题。