手写IOC容器
我们先来看一下IOC容器的整体流程:

首先,我们先创建一个Maven项目,然后在项目的resources目录下添加一个配置文件application.properties,在配置文件中指定需要扫描的包路径

然后我们定义一些注解,分别表示访问控制层、业务服务层、数据持久层、依赖注入注解、获取配置文件注解,代码如下
依赖注入注解@MyAutowired

访问控制层注解@MyController

业务服务层注解@MyService

数据持久层注解@MyMapping

配置文件获取注解@Value

定义完注解后,我们可以开始编写代码了。根据上面的流程图,此时应该先获取读取配置文件,从配置文件中获取需要扫描的包路径
我们先写一个配置文件工具类ConfigurationUtils,代码如下:
package cn.xiaosong.platform.config;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* 类 名: ConfigurationUtils
* @author xiaosong
*/
public class ConfigurationUtils {
/**
* 项目配置文件信息
*/
public static Properties properties;
public ConfigurationUtils(String propertiesPath) {
properties = this.getBeanScanPath(propertiesPath);
}
/**
* @demand: 读取配置文件
*/
private Properties getBeanScanPath(String propertiesPath) {
if (StringUtils.isEmpty(propertiesPath)) {
propertiesPath = "/application.properties";
}
Properties properties = new Properties();
// 通过类的加载器获取具有给定名称的资源
InputStream in = ConfigurationUtils.class.getResourceAsStream(propertiesPath);
try {
System.out.println("正在加载配置文件application.properties");
properties.load(in);
return properties;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return properties;
}
/**
* @demand: 根据配置文件的key获取value的值
*/
public static Object getPropertiesByKey(String propertiesKey) {
if (properties.size() > 0) {
return properties.get(propertiesKey);
}
return null;
}
}
上述代码中,我们通过读取配置文件获取到配置文件信息的key-value键值对;然后我们再根据配置文件中指定的扫描包路径进行包扫描 拿到包扫描路径后,我们就可以获取到当前路径下的文件信息及文件夹信息,我们将当前路径下所有以.class结尾的文件添加到一个Set集合中进行存储。代码如下:
private void classLoader() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// 加载配置文件所有配置信息
new ConfigurationUtils(null);
// 获取扫描包路径
String classScanPath = (String) ConfigurationUtils.properties.get("ioc.scan.path");
if (StringUtils.isNotEmpty(classScanPath)) {
classScanPath = classScanPath.replace(".", "/");
} else {
throw new RuntimeException("请配置项目包扫描路径 ioc.scan.path");
}
// 扫描项目根目录中所有的class文件
getPackageClassFile(classScanPath);
for (String className : classSet) {
addServiceToIoc(Class.forName(className));
}
// 获取带有MyService注解类的所有的带MyAutowired注解的属性并对其进行实例化
Set<String> beanKeySet = iocBeanMap.keySet();
for (String beanName : beanKeySet) {
addAutowiredToField(iocBeanMap.


996

被折叠的 条评论
为什么被折叠?



