什么是IOC
个人感觉ioc就是一个容器嘛,说白也就是个map,spring用的只是线程安全的map罢了。这个map放的是自己注入的对象,这些对象也被称为bean对象。写一个ioc不也就是搞一个map然后把对象放进来,然后自己可以去get,这就是ioc的本质呀!
IOC的一些对象
- BeanDefinition :放置对象的信息,比如:class,scope等等
- BeanFactory : bean工厂对象,里面有实列池,就是map
- BeanPostProcessor : bean的后置处理器,在初始化之前和之后都可以进行处理
- InitializingBean : 初始化接口
IOC实例化的流程
- 遍历所有的class,将其解析成BeanDefinition对象
- 实例化对象,就是new 一个无参的
- 给对象属性赋值
- 初始化接口
- 后置处理器
- 放入map
这是我自己实现的步骤,spring的具体步骤和顺序大家可以自行百度
实现逻辑
- 遍历所有的class,将其解析成BeanDefinition对象:
/**
* 解析对象成beanDefinition
*
* @param allClass
*/
public void initBeanDefinitions(List<Class<?>> allClass) {
allClass.forEach((item) -> {
if (item.isAnnotationPresent(Configuration.class)) {
beanFactoryUtil.setBeanDefinition(item);
Method[] declaredMethods = item.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if (declaredMethod.isAnnotationPresent(Bean.class)) {
Parameter[] parameters = declaredMethod.getParameters();
Bean annotation = declaredMethod.getDeclaredAnnotation(Bean.class);
Class returnType = declaredMethod.getReturnType();
if (returnType.getName().equals("void")) {
} else {
Object invoke = null;
try {
invoke = declaredMethod.invoke(item.newInstance(), parameters);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
if (annotation.value().equals("")) {
beanFactoryUtil.setSingletonObject(declaredMethod.getName(), invoke);
} else {
beanFactoryUtil.setSingletonObject(annotation.value(), invoke);
}
}
}
}
}
if (item.isAnnotationPresent(Component.class)) {
Component declaredAnnotation = item.getDeclaredAnnotation(Component.class);
if (declaredAnnotation.value().equals("")) {
beanFactoryUtil.setBeanDefinition(item);
} else {
beanFactoryUtil.setBeanDefinition(item, declaredAnnotation.value());
}
}
if (item.isAnnotationPresent(Controller.class)) {
Controller declaredAnnotation = item.getDeclaredAnnotation(Controller.class);
if (declaredAnnotation.value().equals("")) {
beanFactoryUtil.setBeanDefinition(item);
} else {
beanFactoryUtil.setBeanDefinition(item, declaredAnnotation.value());
}
}
});
}
public void setBeanDefinition(Class clazz) {
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setClazz(clazz);
beanDefinition.setBeanName(clazz.getSimpleName());
if (clazz.isAnnotationPresent(Scope.class)) {
Scope declaredAnnotation = (Scope) clazz.getDeclaredAnnotation(Scope.class);
if (declaredAnnotation.value().equals("")) {
beanDefinition.setScope("singleton");
} else {
beanDefinition.setScope(declaredAnnotation.value());
}
} else {
beanDefinition.setScope("singleton");
}
if (BeanPostProcessor.class.isAssignableFrom(clazz)) {
beanDefinition.setBeanPostProcessor(true);
} else {
beanDefinition.setBeanPostProcessor(false);
}
if (DateHandle.class.isAssignableFrom(clazz)) {
beanDefinition.setDateHandle(true);
} else {
beanDefinition.setDateHandle(false);
}
if (WebMvcConfigurer.class.isAssignableFrom(clazz)) {
beanDefinition.setWebMvcConfigurer(true);
} else {
beanDefinition.setWebMvcConfigurer(false);
}
if(clazz.isAnnotationPresent(Aspect.class)){
beanDefinition.setAspect(true);
}else {
beanDefinition.setAspect(false);
}
if(clazz.isAnnotationPresent(Controller.class)){
beanDefinition.setController(true);
}else {
beanDefinition.setController(false);
}
beanFactory.setBeanDefinition(beanDefinition);
}
- clazz.newInstance();
- 属性赋值,我只定义了一个注解
public void autowiredHandle(Object newInstance, Field declaredField,
ConcurrentHashMap<String, Object> originalObjects,
ConcurrentHashMap<String, Object> singletonObjects
) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
if (declaredField.getModifiers() == 2 || declaredField.getModifiers() == 10
|| declaredField.getModifiers() == 26 || declaredField.getModifiers() == 18) {
declaredField.setAccessible(true);
}
if (declaredField.isAnnotationPresent(Autowired.class)) {
ArrayList<Object> objects = new ArrayList<>();
singletonObjects.forEach((key, value) -> {
if (declaredField.getType().isAssignableFrom(value.getClass())) {
objects.add(value);
}
});
if (objects.size() == 0) {
List<BeanDefinition> beanDefinitions1 = beanFactoryUtil.getBeanDefinition(declaredField.getType());
if (beanDefinitions1.size() == 0) {
} else {
if (beanDefinitions1.size() == 1) {
Object bean = getBean(beanDefinitions1.get(0), originalObjects, singletonObjects);
declaredField.set(newInstance, bean);
} else {
for (BeanDefinition definition : beanDefinitions1) {
if (declaredField.getName().equals(definition.getBeanName())) {
Object bean = getBean(definition, originalObjects, singletonObjects);
declaredField.set(newInstance, bean);
}
}
}
}
} else {
if (objects.size() == 1) {
try {
declaredField.set(newInstance, objects.get(0));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} else {
singletonObjects.forEach((key, value) -> {
if (key.equals(declaredField.getName())) {
try {
declaredField.set(newInstance, value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
});
}
}
}
}
4.初始化接口这个就是你bean对象如果实现了这个接口,属性赋值完之后就调用这个接口的方法,就这样而已
if (finalNewInstance1 instanceof InitializingBean) {//初始化
InitializingBean initializingBean = (InitializingBean) finalNewInstance1;
initializingBean.afterPropertiesSet();
}
- 后置处理器跟初始话一样的,2个方法,初始化之前,初始化之后
beanPostProcessorOrders.forEach((beanPostProcessorOrder -> {//bean前置处理器--初始化之前
beanPostProcessorOrder.getBeanPostProcessor().postProcessBeforeInitialization(finalNewInstance1, beanDefinition.getBeanName());
}));
if (finalNewInstance1 instanceof InitializingBean) {//初始化
InitializingBean initializingBean = (InitializingBean) finalNewInstance1;
initializingBean.afterPropertiesSet();
}
beanPostProcessorOrders.forEach((beanPostProcessorOrder -> {//bean后置处理器--初始化之后
beanPostProcessorOrder.getBeanPostProcessor().postProcessAfterInitialization(finalNewInstance1, beanDefinition.getBeanName());
}));
- 放入map就很简单了,,我就不搞代码了,对了有个单例,多例的注解,记得去判断一下,有的就直接从map里面拿,多例就每次创建。还有哈,我这些都在getBean方法里面,用户每次用的时候去实例化,不是一次都实例化好,这样也可以,应该算不同的模式吧,你们可以自己实现一下,搞个啥注解控制。
经典问题
循环依赖: 就是有个A里面有个B属性,B有A属性
正常流程:实例化A , A属性注入时发现B,然后去实例化B,B属性注入时发现A,又去实例化A,这不就死循环了
解决方法:搞一个map出来,充当缓存,每次实例化之后就放入缓存中,那的话先从单例池map拿,没有就去这个缓存map中拿就ok了
这就是二级缓存,2个map。这样可以解决循环依赖问题,不过spring用的三级缓存,原因就是aop,这个大家百度一下,大概就是为了存下aop代理之后的对象,我这边没有用3级缓存,只用了2级。aop功能也实现了,不过可能有bug,可能,嗯~~
总结
这就是我写的ioc主要类容了,本次类容和下次都是去详细讲一下
https://blog.csdn.net/qq_43110503/article/details/119722286?spm=1001.2014.3001.5501
这篇博客的内容
本人今年毕业,说错的地方大家指出别用太暴力的方式,, 球球了。
白天上班,晚上不加班,有精力,有心情的时候 去跟新后面的内容!!!