我的源码:https://github.com/lldwb/lldwb_ioc.git
介绍
提示:实现简单的ioc容器是为了学习并加深ioc的概念
IoC容器 = IOC + 容器(Bean容器/容器工厂)
容器工厂就使用反射获取类的容器工厂(终极版)
只需要在这个容器工厂的基础下扩展ioc的功能就可以了
ioc容器生命周期(单例)
- 创建:读取并创建和存储需要管理的依赖
- 依赖注入:全部完成创建后进行依赖注入
ioc容器生命周期(原型)
- 创建:读取并存储需要管理的依赖(class格式)
- 使用:读取 ioc 容器中的 class 进行创建,创建后进行依赖注入,依赖注入时会检索保证所使用的所有依赖(包括依赖的依赖)都可以正常使用
思路介绍
请先根据思路完成一遍,再看我的或者其他人的源码
- 完成容器工厂
- 添加 ioc(依赖注入)的功能,注意:单例是在全部完成创建后进行依赖注入,而原型在自己创建后进行依赖注入
源码介绍
注入处理器调用者
用于找到注入处理器的实现类,并遍历所有实现类进行调用
@Slf4j
public class InjectHandlerInvoker {
private static List<InjectHandler> list=new ArrayList<>();
static {
for (Class<?> clazz:ScanUtils.scan(InjectHandler.class,"top.lldwb.ioc.inject.impl")){
try {
Object object = clazz.newInstance();
if (InjectHandler.class.isInstance(object)){
list.add((InjectHandler) object);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
}
}
public static Object handle(Object object, ContainerFactory factory) {
for (InjectHandler injectHandler : list) {
injectHandler.handle(object, factory);
}
return object;
}
}
注入处理器接口
注入处理器接口,如果需要扩展注入处理器的功能请实现该接口
public interface InjectHandler {
Object handle(Object object, ContainerFactory factory);
}
字段注入处理器实现类
@Slf4j
public class MethodInjectHandler implements InjectHandler {
@Override
public Object handle(Object object, ContainerFactory factory) {
log.debug("遍历公开方法,查看是否需要依赖注入");
try {
// 获取 object 及其指定到父类 Object 的 BeanInfo
// 方法信息
for (Method method : object.getClass().getMethods()) {
if (method.isAnnotationPresent(Inject.class)) {
log.debug("method:" + method.getName());
List<Object> objectList = new ArrayList<>();
log.debug("获取方法的每个参数");
for (Parameter parameter : method.getParameters()) {
log.debug("遍历参数");
if (factory.isMultipleClass(parameter.getClass())) {
log.debug("一个实现类时执行");
log.debug("参数类型:" + parameter.getType().getName());
objectList.add(factory.getBean(parameter.getType()));
} else {
log.debug("多个实现类时执行");
Inject inject = method.getAnnotation(Inject.class);
log.debug("注解指定的实现类:" + inject.value());
objectList.add(factory.getBean(inject.value()));
}
}
method.invoke(object, objectList.stream().toArray());
}
}
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return object;
}
}
方法注入处理器实现类
@Slf4j
public class FieldInjectHandler implements InjectHandler {
@Override
public Object handle(Object object, ContainerFactory factory) {log.debug("遍历所有字段,查看是否需要依赖注入(不推荐)");
for (Field field : object.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Inject.class)) {
log.debug("field:" + field.getName());
Inject inject = field.getAnnotation(Inject.class);
Object value;
if (inject.value() != "") {
value = factory.getBean(inject.value());
} else {
value = factory.getBean(field.getType());
}
try {
field.setAccessible(true);
field.set(object, value);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
return object;
}
}
工厂
@Slf4j
public class ContainerFactory {
/**
* 单例容器
*/
private Map<String, Object> container = new HashMap<>();
/**
* 原型容器
*/
private Map<String, Class<?>> archetype = new HashMap<>();
/**
* 初始化容器
* 参数表示要管理的包路径
*/
public ContainerFactory(String... packages) {
List<Class<?>> classList = ScanUtils.scan(packages);
resolveClass(classList);
}
/**
* 容器工厂方法
*/
public Object getBean(String name) {
if (container.containsKey(name)) {
return container.get(name);
} else {
Object object = newInstance(archetype.get(name));
if (object == null) {
throw new RuntimeException();
}
return inject(object);
}
}
/**
* 容器工厂方法
*/
public <T> T getBean(String name, Class<T> tClass) {
// 判断单例容器中是否有
if (container.containsKey(name)) {
return (T) container.get(name);
} else {
T t = (T) newInstance(archetype.get(name));
if (t == null) {
throw new RuntimeException();
}
inject(t);
return t;
}
}
/**
* 容器工厂方法
*/
public <T> T getBean(Class<T> tClass) {
// 判断单例容器中是否有
T t = null;
for (Object objects : container.values()) {
// 判断是否可以进行类型转换
if (tClass.isInstance(objects)) {
if (t != null) {
throw new RuntimeException();
}
t = (T) objects;
}
}
for (Class<?> clazz : archetype.values()) {
// 判断是否可以进行类型转换
try {
Object objects = clazz.newInstance();
if (tClass.isInstance(objects)) {
if (t != null) {
throw new RuntimeException();
}
t = (T) objects;
inject(t);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
}
if (t == null) {
throw new RuntimeException();
}
return t;
}
/**
* 解析class集合,找到带有@Bean注解的类
* 同时对单例容器进行依赖注入
*
* @param classList
*/
private void resolveClass(List<Class<?>> classList) {
classList.forEach(clazz -> {
if (clazz.isAnnotationPresent(Bean.class)) {
Bean bean = clazz.getAnnotation(Bean.class);
// 获取 Bean 的作为 k
String k = bean.value();
// 判断是否需要唯一
if (bean.sole()) {
// 唯一,添加到单例容器
container.put(k, newInstance(clazz));
} else {
// 不唯一,添加到原型容器
archetype.put(k, clazz);
}
}
});
// 对单例容器进行依赖注入
for (Object object : container.values()) {
inject(object);
}
}
/**
* 判断接口是否多个实现类
*
* @param tClass
* @return 有多个返回 false
*/
public Boolean isMultipleClass(Class<?> tClass) {
// 判断单例容器中是否有
Boolean is = false;
for (Object objects : container.values()) {
// 判断是否可以进行类型转换
if (tClass.isInstance(objects)) {
if (is) {
return false;
} else {
is = true;
}
}
}
for (Class<?> clazz : archetype.values()) {
// 判断是否可以进行类型转换
try {
Object objects = clazz.newInstance();
if (tClass.isInstance(objects)) {
if (is) {
return false;
} else {
is = true;
}
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
}
}
return is;
}
/**
* 创建实例
*
* @param clazz 类
* @return
*/
private Object newInstance(Class<?> clazz) {
try {
return clazz.getConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("实例创建失败:", e);
}
}
/**
* 进行依赖注入
*
* @param object
* @return
*/
private Object inject(Object object) {
log.debug(object.getClass().getName() + "进行依赖注入");
InjectHandlerInvoker.handle(object,this);
return object;
}
}