// 1.7 在通过这个clazz(类)来判断是否有component注解,有则是beanif (clazz.isAnnotationPresent(Component.class)) { Component annotation = clazz.getAnnotation(Component.class); String beanName = annotation.value(); // * 默认生成bean,如果只使用Component注解,没有写上beanName的值,那么就需要自动生成 if (beanName.equals("")) { // 默认开头小字母 beanName = Introspector.decapitalize(clazz.getSimpleName()); } /** * 這就是一个bean了 * 然而在这里并不是直接就创建bean了,bean分为了单例bean和多例bean */ BeanDefinition beanDefinition = new BeanDefinition(); beanDefinition.setType(clazz); if (clazz.isAnnotationPresent(Scope.class)) { // 判断是单例还是多例Scope scope = clazz.getAnnotation(Scope.class);beanDefinition.setScope(scope.value()); } else {beanDefinition.setScope("singleton"); } beanDefinitionMap.put(beanName, beanDefinition);}getBean底层通过传来一个beanName , 通过beanDefinitionMap中获取key为beanName的BeanDefinition对象,进行判空处理 。这样我们可以通过这个BeanDefinition对象去获取作用域,判断是否为单例 。
获取bean在此,我们创建单例的时候,是需要将单例保存起来的,需要定义ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();单例池来保存单例bean 。然后在getBean的时候,如果是单例bean,就可以先去单例池中寻找,如果没找到,再去创建对象 。而多例模式就需要每次都去创建 。
// 获取bean对象public Object getBean(String beanName) { BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); if (beanDefinition == null) { throw new NullPointerException("找不到bean名字为[" + beanName + "]的bean对象"); } else { // 找到就做相应的操作 String scope = beanDefinition.getScope(); if (scope.equals("singleton")) { // 通过单例池获取 Object bean = singletonObjects.get(beanName); if (bean == null) { // 单例池中如果没有bean,就需要去创建 bean = createBean(beanName, beanDefinition); singletonObjects.put(beanName, bean); } return bean; } else { // 多例的就不需要记录 , 每次都是通过创建 return createBean(beanName, beanDefinition); } }}创建bean利用反射机制,通过无参构造方法去获取实例,这里就是bean对象实例了 。就可以直接返回 。
// 创建beanprivate Object createBean(String beanName, BeanDefinition definition) { // 利用反射获取实例 , 采用无参构造方法 Class clazz = definition.getType(); // 通过无参构造方法获取实例 try {Object instance = clazz.getConstructor().newInstance(); // 到这里直接返回,bean的对象也就创建完成return instance; } catch (InstantiationException e) {e.printStackTrace(); } return null;}在构造方法扫描后要根据生成的beanDefinitionMap去创建单例bean对象 。
// 2 创建单例bean对象for (String beanName : beanDefinitionMap.keySet()) { BeanDefinition beanDefinition = beanDefinitionMap.get(beanName); if (beanDefinition.getScope().equals("singleton")) { // 那么,如何保证单例呢?就需要有个单例池,singletonObjects Object bean = createBean(beanName, beanDefinition); singletonObjects.put(beanName, bean); // 将单例bean存到单例池中 }}
推荐阅读
- 【ASP.NET Core】MVC控制器的各种自定义:应用程序约定的接口与模型
- 基础版 【网络】内网穿透方案&FRP内网穿透实战
- FGO日服七周年礼装自选哪个好
- 蚂蚁庄园今日答题答案是什么
- iqooneo5是什么屏幕_iqooneo5屏幕尺寸参数
- 原神如何去雷神的岛屿(原神如何上雷神岛)
- 一次SpringBoot版本升级,引发的血案
- 中 学习ASP.NET Core Blazor编程系列十——路由
- 小米11和vivox60哪个好_小米11和vivox60参数对比
- 苹果13mini屏幕多大尺寸_苹果13mini屏幕尺寸
