手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】实现任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入

前言
手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】的第四篇实现了任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入

个人主页:尘觉主页

个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力

在csdn获奖荣誉: csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣  端午大礼包获得者

欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦

文章目录

  • 实现任务阶段 3- 初始化 bean 单例池,并完成 getBean 方法 , createBean 方法
    • 修改WyxSpringApplicationContext类
      • 增加相应的业务代码
    • 修改AppMain
    • 完成测试,输出效果
  • 实现任务阶段 4- 完成依赖注入
    • ● 分析示意图
      • 创建Autowired.java注解
      • 修改MonsterDao类
      • 修改MonsterService.java类
      • 修改WyxSpringApplicationContext类
      • 修改AppMain
      • 运行完成测试
    • 总结

实现任务阶段 3- 初始化 bean 单例池,并完成 getBean 方法 , createBean 方法

说明: 初始化 bean 单例池,并完成 getBean 方法 , createBean 方法

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】实现任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入_第1张图片

修改WyxSpringApplicationContext类

增加相应的业务代码

  • 通过扫描,得到 beanDefinition 的 map
  • 通过 beanDefinitionMap , 初始化 singletonObjects bean 单列池
  • 得到 beanName
  • 通过 beanName 得到 beanDefinition
 public WyxSpringApplicationContext(Class configClass) {
            //通过扫描,得到 beanDefinition 的 map
        beanDefinitionsByscan(configClass);
        System.out.println(beanDefinitionMap);
        //通过 beanDefinitionMap , 初始化 singletonObjects bean 单列池
        Enumeration<String> keys = beanDefinitionMap.keys();
        while (keys.hasMoreElements()) {
            //得到 beanName
            String beanName = keys.nextElement();
            //通过 beanName 得到 beanDefinition
            BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
            if ("singleton".equalsIgnoreCase(beanDefinition.getScope())) {
                //将该 bean 实例放入 singletonObjects
                Object bean = createBean(beanDefinition);
                singletonObjects.put(beanName, bean);
            }
        }
        System.out.println("singletonObjects 单例池 = " + singletonObjects);
    }
    //先简单实现实现,后面在完善.
    private Object createBean(BeanDefinition beanDefinition) {
            //得到 bean 的类型
        Class clazz = beanDefinition.getClazz();
        try {
            //使用反射得到实例
            Object instance = clazz.getDeclaredConstructor().newInstance();
            return instance;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //如果没有创建成功,返回 null
        return null;
    }
    public Object getBean(String name) {
        if(beanDefinitionMap.containsKey(name)) {
            BeanDefinition beanDefinition = beanDefinitionMap.get(name);
            //得到 bean 的 scope , 分别处理
            if("singleton".equalsIgnoreCase(beanDefinition.getScope())) {
            //单例,直接从 bean 单例池获取
                return singletonObjects.get(name);
            } else { //不是单例,则没有返回新的实例
                return createBean(beanDefinition);
            }
        } else {
            throw new NullPointerException("没有该 bean");
        }
    }

修改AppMain

public class AppMain {
    public static void main(String[] args) {
        //创建我们的 spring 容器对象
        HspSpringApplicationContext hspSpringApplicationContext =
                new HspSpringApplicationContext(HspSpringConfig.class);
        //通过 spring 容器对象, 获取 bean 对象
        System.out.println(hspSpringApplicationContext.getBean("monsterService"));
        System.out.println(hspSpringApplicationContext.getBean("monsterService"));
        System.out.println(hspSpringApplicationContext.getBean("monsterService"));
    }
}

完成测试,输出效果

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】实现任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入_第2张图片

实现任务阶段 4- 完成依赖注入

● 分析示意图

手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】实现任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入_第3张图片

● 代码实现, 说明,整个实现思路,就是参考 Spring 规范

创建Autowired.java注解

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
//这里属性,可以参考思路完成,还是比较简单
    //boolean required() default true;
}

修改MonsterDao类

@Component("monsterDao")
public class MonsterDao {
public void hi() {
System.out.println("hi 我是 monster Dao, select * from ....");
}
}

修改MonsterService.java类

@Component("monsterService")
@Scope("prototype")
public class MonsterService implements InitializingBean {
    @Autowired
    private MonsterDao monsterDao;
    public void m1() {
        //调用 monsterDao 的 hi()
        monsterDao.hi();
    }
}

修改WyxSpringApplicationContext类

 // 先简单实现实现,后面在完善. private Object createBean(BeanDefinition beanDefinition) {
    // 得到 bean 的类型
    Class clazz = beanDefinition.getClazz();
    try
    {
        // 使用反射得到实例
        Object instance = clazz.getDeclaredConstructor().newInstance();
        // 完成依赖注入
        for (Field declaredField : clazz.getDeclaredFields()) {
            if (declaredField.isAnnotationPresent(Autowired.class)) {
                // 处理@Autowired 注解的属性 required, 很简单,自己完成
                // Autowired annotation =
                declaredField.getAnnotation(Autowired.class);
                // System.out.println(annotation.required());
                // 如果该属性有@Autowired, 就进行组装
                Object bean = getBean(declaredField.getName());
                declaredField.setAccessible(true);// 因为属性是 private,需要暴破
                declaredField.set(instance, bean);
            }
        }
        return instance;
    } catch(InstantiationException e){
        e.printStackTrace();
    } catch(IllegalAccessException e){
        e.printStackTrace();
    } catch(InvocationTargetException e){
        e.printStackTrace();
    } catch(NoSuchMethodException e){
        e.printStackTrace();
    }
 // 如果没有创建成功,返回 null
   return null;
}

修改AppMain

public class AppMain {
    public static void main(String[] args) {
        //创建我们的 spring 容器对象
        WyxSpringApplicationContext wyxSpringApplicationContext =
                new WyxSpringApplicationContext(WyxSpringConfig.class);
        //通过 spring 容器对象, 获取 bean 对象
        //System.out.println(hspSpringApplicationContext.getBean("monsterService"));
        //System.out.println(hspSpringApplicationContext.getBean("monsterService"));
        //System.out.println(hspSpringApplicationContext.getBean("monsterService"));
        MonsterService monsterService = (MonsterService)
                wyxSpringApplicationContext.getBean("monsterService");
        monsterService.m1();
    }
}

运行完成测试

img

总结

本文完成了手动实现 Spring 底层机制实现任务阶段 3- 初始化 bean 单例池 和 实现任务阶段 4- 完成依赖注入后面会完成bean 后置处理器
 
  
  
  
手动实现 Spring 底层机制【初始化 IOC容器+依赖注入+BeanPostProcessor 机制+AOP】系列

手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【1】

手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器-准备篇【2】

手动实现 Spring 底层机制 实现任务阶段一编写自己 Spring 容器,实现任务阶段 2- 扫描将 bean 信息封装到 BeanDefinition 对象
          
               
                
热门专栏推荐

想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读
如果帮助到您不妨3连支持一

你可能感兴趣的:(#,手写机制,spring,java,后端,spring,boot,java-ee,maven,log4j)