当前位置: 首页 > news >正文

南京高端模板建站自媒体培训学校

南京高端模板建站,自媒体培训学校,公司国外网站建设,滨海做网站的文章目录 一、目标:实现Bean的定义、注册、获取二、设计:实现Bean的定义、注册、获取三、实现:实现Bean的定义、注册、获取3.1 工程结构3.2 实现Bean的定义、注册、获取类图3.3 定义Bean异常3.4 BeanDefinition定义和注册3.4.1 BeanDefinitio…

文章目录

  • 一、目标:实现Bean的定义、注册、获取
  • 二、设计:实现Bean的定义、注册、获取
  • 三、实现:实现Bean的定义、注册、获取
    • 3.1 工程结构
    • 3.2 实现Bean的定义、注册、获取类图
    • 3.3 定义Bean异常
    • 3.4 BeanDefinition定义和注册
      • 3.4.1 BeanDefinition定义
      • 3.4.2 BennDefinition定义注册接口
    • 3.5 单例注册接口定义和实现
      • 3.5.1 单例注册接口
      • 3.5.2 单例注册接口的实现
    • 3.6 抽象类定义模板方法
      • 3.6.1 Bean工厂接口
      • 3.6.2 抽象Bean工厂基类,定义模板方法
      • 3.6.3 实例化Bean类
      • 3.6.4 核心类:默认的Bean工厂实现
  • 四、测试:实现Bean的定义、注册、获取
  • 五、总结:实现Bean的定义、注册、获取

一、目标:实现Bean的定义、注册、获取

💡 实现 Bean 容器关于 Bean 对象的注册和获取?

  • Bean 的创建交给容器,而不是我们在调用时候传递一个实例化好的 Bean 对象。
  • 另外还需要考虑单例对象,在对象的二次获取时是可以从内存中获取对象的。
  • 此外不仅要实现功能还需要完善基础容器框架的类结构体,否则将来就很难扩容进去其他的功能。

二、设计:实现Bean的定义、注册、获取

💡 实现Bean的定义、注册、获取?

  • 首先是在 Bean 注册的时候只注册一个类信息,而不会直接把实例化信息注册到 Spring 容器中。
  • 那么就需要修改 BeanDefinition 中的属性 ObjectClass,接下来就是在获取 Bean 对象时需要处理 Bean 对象的实例化操作以及判断当前单例对象在容器中是否已经缓存起来。

在这里插入图片描述

  • 首先需要定义 BeanFactory 这样一个 Bean 工厂,提供 Bean 的获取方法 getBean(String name),之后这个 Bean 工厂接口由抽象类 AbstractBeanFactory 实现。
    • 这样用 模板模式 的设计方式,可以统一设计通用核心方法的调用逻辑和标准定义,也就很好的控制了后续的实现者不用关心调用逻辑。
    • 按照统一方式执行。那么类型的继承者只需要关心具体方法的逻辑实现即可。
  • 在继承抽象类 AbstractBeanFactory 后的 AbstractAutowireCapableBeanFactory 就可以实现相应的抽象方法了。
    • 因为 AbstractAutowireCapableBeanFactory 本身也是一个抽象类,所以它只会实现属于自己的抽象方法,其他抽象方法由继承 AbstractAutowireCapableBeanFactory 的类实现。
    • 这里就体现了类实现过程中的各司其职,你只需要关心属于你的内容,不是你的内容,不要参与。
  • 另外还有块重要的知识点,就是关于单例 SingletonBeanRegistry 的接口定义实现,而 DefaultSingletonBeanRegistry 对接口实现后,会被抽象类 AbstractBeanFactory 继承。
    • 现在 AbstractBeanFactory 就是一个非常完整且强大的抽象类了,也能非常好的体现出它对模板模式的抽象定义。

三、实现:实现Bean的定义、注册、获取

3.1 工程结构

spring-step-02
|-src|-main|   |-java|       |-com.lino.springframework|           |-factory|           |   |-config|           |   |   |-BeanDefinition.java|           |   |   |-SingletonBeanRegistry.java|           |   |-support|           |   |   |-AbstractAutowireCapableBeanFactory.java|           |   |   |-AbstractBeabFactory.java|           |   |   |-BeanDefinitionRegistry.java|           |   |   |-DefaultListableBeanFactory.java|           |   |   |-DefaultSingletonBeanRegistry.java|           |   |-BeanFactory.java|           |-BeansException.java|-test|-java|-com.lino.springframework.test|-bean|   |-UserService.java|-ApiTest.java

3.2 实现Bean的定义、注册、获取类图

在这里插入图片描述

  • Spring Bean 容器的功能实现,已经具备了一定的设计复杂性,这些复杂的类关系设计在各个接口定义和实现以及在抽象类继承中都有所体现。
    • BeanFactory 的定义由 AbstractBeanFactory 抽象类实现接口的 getBean 方法。
    • AbstractBeanFactory 又继承实现了 SingletonBeanRegistryDefaultSingletonBeanRegistry 类。这样 AbstractBeanFactory 抽象类就具备了单例 Bean 的注册功能。
    • AbstractBeanFactory 中又定义了两个抽象方法:getBeanDefinition(String beanName)createBean(String beanName, BeanDefinition beanDefinition),这两个抽象方法分别由 DefaultListableBeanFactoryAbstractAutowireCapableBeanFactory 实现。
    • 最终 DefaultListableBeanFactory 还会继承抽象类 AbstractAutowireCapableBeanFactory 也就可以调用抽象类中的 createBean 方法了。
  • 所有的实现都以职责划分、共性分离以及调用关系定义为标准搭建的类关系。

3.3 定义Bean异常

BeansException.java

package com.lino.springframework;/*** @description: 定义 Bean 异常*/
public class BeansException extends RuntimeException {public BeansException(String msg) {super(msg);}public BeansException(String msg, Throwable cause) {super(msg, cause);}
}

3.4 BeanDefinition定义和注册

3.4.1 BeanDefinition定义

BeanDefinition.java

package com.lino.springframework.factory.config;/*** @description: Bean 对象信息定义*/
public class BeanDefinition {/*** bean对象*/private Class beanClass;public BeanDefinition(Class beanClass) {this.beanClass = beanClass;}public Class getBeanClass() {return beanClass;}public void setBeanClass(Class beanClass) {this.beanClass = beanClass;}
}
  • Bean 定义类中把 Object 替换为 Class,这样就可以把 Bean 的实例化操作放到容器中处理了。

3.4.2 BennDefinition定义注册接口

BeanDefinitionRegistry.java

package com.lino.springframework.factory.support;import com.lino.springframework.factory.config.BeanDefinition;/*** @description: Bean 定义注册接口*/
public interface BeanDefinitionRegistry {/*** 向注册表中注册 BeanDefinition** @param beanName       Bean 名称* @param beanDefinition Bean 定义*/void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
  • Bean 定义注册接口只有一个接口方法,就是向注册表中注册 BeanDefinition

3.5 单例注册接口定义和实现

3.5.1 单例注册接口

SingletonBeanRegistry

package com.lino.springframework.factory.config;/*** @description: 单例 Bean 注册表*/
public interface SingletonBeanRegistry {/*** 返回在给定名称下注册的(原始)单例对象** @param beanName 要查找的bean的名称* @return 返回注册的单例对象*/Object getSingleton(String beanName);/*** 注册单例对象** @param beanName        Bean 对象名称* @param singletonObject Bean 对象*/void registerSingletonBean(String beanName, Object singletonObject);
}
  • 这个类比较简单,主要是定义了一个获取单例对象和注册单例对象的接口。

3.5.2 单例注册接口的实现

DefaultSingletonBeanRegistry.java

package com.lino.springframework.factory.support;import com.lino.springframework.factory.config.SingletonBeanRegistry;
import java.util.HashMap;
import java.util.Map;/*** @description: 通用的注册表实现*/
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {private Map<String, Object> singletonObjects = new HashMap<>();@Overridepublic Object getSingleton(String beanName) {return singletonObjects.get(beanName);}@Overridepublic void registerSingletonBean(String beanName, Object singletonObject) {singletonObjects.put(beanName, singletonObject);}
}
  • DefaultSingletonBeanRegistry 主要实现 getSingleton 方法和 registerSingletonBean 方法。

3.6 抽象类定义模板方法

3.6.1 Bean工厂接口

BeanFactory.java

package com.lino.springframework.factory;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @description: 定义 Bean 工厂接口*/
public interface BeanFactory {/*** 返回 Bean 的实例对象** @param name 要检索的bean的名称* @return 实例化的 Bean 对象* @throws BeansException 不能获取 Bean 对象,抛出异常*/Object getBean(String name) throws BeansException;
}

3.6.2 抽象Bean工厂基类,定义模板方法

AbstractBeanFactory.java

package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.BeanFactory;
import com.lino.springframework.factory.config.BeanDefinition;/*** @description: 抽象的 Bean 工厂基类,定义模板方法*/
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements BeanFactory {@Overridepublic Object getBean(String name) throws BeansException {Object bean = getSingleton(name);if (bean != null) {return bean;}BeanDefinition beanDefinition = getBeanDefinition(name);return createBean(name, beanDefinition);}/*** 获取 Bean 对象** @param beanName 要检索的bean的名称* @return Bean 对象*/protected abstract BeanDefinition getBeanDefinition(String beanName);/*** 创建Bean对象** @param beanName       要检索的bean的名称* @param beanDefinition Bean对象* @return 实例化的Bean对象*/protected abstract Object createBean(String beanName, BeanDefinition beanDefinition);
}
  • AbstractBeanFactory 首先继承了 DefaultSingletonBeanRegistry,也就具备了使用单例注册类方法。
  • 接下来很重要的一点是关于接口 BeanFactory 的实现。
    • 在方法 getBean 的实现过程中可以看到,主要是对单例 Bean 对象的获取以及在获取不到时需要拿到 Bean 的定义做相应 Bean 实例化操作。
    • 那么 getBean 并没有自身的去实现这些方法,而是只定义了调用过程以及提供了抽象方法,由实现此抽象类的其他类做相应实现。
  • 后续继承抽象类 AbstractBeanFactory 的类有两个。
    • 包括:AbstractAutowireCapableBeanFactoryDefaultListableBeanFactory,这两个类分别做了相应的实现处理。

3.6.3 实例化Bean类

AbstractAutowireCapableBeanFactory.java

package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;/*** @description: 实现默认bean创建的抽象bean工厂超类*/
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {@Overrideprotected Object createBean(String beanName, BeanDefinition beanDefinition) {Object bean = null;try {bean = beanDefinition.getBeanClass().newInstance();} catch (InstantiationException | IllegalAccessException e) {throw new BeansException("Instantiation of bean failed", e);}registerSingletonBean(beanName, bean);return bean;}
}
  • AbstractAutowireCapableBeanFactory 类中实现了 Bean 的实例化操作 newInstance
  • 在处理完 Bean 对象的实例化后,直接调用 registerSingletonBean 方法存放到单例对象的缓存中去。

3.6.4 核心类:默认的Bean工厂实现

DefaultListableBeanFactory.java

package com.lino.springframework.factory.support;import com.lino.springframework.BeansException;
import com.lino.springframework.factory.config.BeanDefinition;
import java.util.HashMap;
import java.util.Map;/*** @description: 默认的Bean工厂实现类*/
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry {private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();@Overrideprotected BeanDefinition getBeanDefinition(String beanName) {BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);if (beanDefinition == null) {throw new BeansException("No bean named '" + beanName + "' is defined");}return beanDefinition;}@Overridepublic void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {beanDefinitionMap.put(beanName, beanDefinition);}
}
  • DefaultListableBeanFactorySpring 的源码中也是一个非常核心的类。
  • DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 类,也就具备了接口 BeanFactoryAbstractBeanFactory 等一连串的功能实现。
  • 除此之外这个类还实现了接口 BeanDefinitionRegistry 中的 registerBeanDefinition(String beanName, BeanDefinition beanDefinition) 方法。
    • 还会看到一个 getBeanDefinition 的实现,这个方法是抽象类 AbstractBeanFactory 中定义的抽象方法。现在注册 Bean 定义与获取 Bean 定义就可以同时使用了。
    • 接口定义了注册,抽象类定义了获取,都集中在 DefaultListableBeanFactory 中的 beanDefinitionMap 里。

四、测试:实现Bean的定义、注册、获取

ApiTest.java

@Test
public void test_BeanFactory() {// 1.初始化 BeanFactoryDefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();// 2.注册beanBeanDefinition beanDefinition = new BeanDefinition(UserService.class);beanFactory.registerBeanDefinition("userService", beanDefinition);// 3.第一次获取beanUserService userService = (UserService) beanFactory.getBean("userService");userService.queryUserInfo();// 3.第二次获取beanUserService userService_singleton = (UserService) beanFactory.getBean("userService");userService_singleton.queryUserInfo();
}
  • 在此次的单元测试中处理包括:Bean 工厂、注册 Bean、获取 Bean 三个步骤,还额外增加了一次对象的获取和调用。
    • 这里主要测试验证单例对象是否正确的存放到了缓存中。
  • 此时,我们把 UserService.class 传递给了 BeanDefinition

测试结果

查询用户信息查询用户信息

在这里插入图片描述

  • 这里会有两次测试信息,一次是获取 Bean 时直接创建的对象,另外一次是从缓存中获取的实例化对象。
  • 此外从调试的截图中看出第二次获取单例对象,是从内存中获取的。

五、总结:实现Bean的定义、注册、获取

  • Spring Bean 容器的实现类中要重点关注类之间的职责和关系,几乎所有的程序功能设计都离不开接口、抽象类、实现、继承。
    • 而这些不同特性类的使用就可以非常好的隔离开类的功能职责和作用范围。
http://www.15wanjia.com/news/50878.html

相关文章:

  • 濮阳网站建设公司网页设计是干嘛的
  • 手机做照片下载网站培训课程表
  • 高端定制网站建设制作培训seo去哪家机构最好
  • 福田做商城网站建设找哪家公司比较安全广州seo效果
  • 大庆做网站公司美区下载的app怎么更新
  • 哪个网站做美食视频软件广州seo黑帽培训
  • 数字广东网络建设有限公司是国企吗seo网络排名优化哪家好
  • 怎么邀约客户做网站品牌宣传推广方案
  • 做网站的流程分析如何做线上销售和推广
  • 体育网站建设的必要性长沙网站seo外包
  • 深圳营销网站建设模板手机系统流畅神器
  • 濮阳做网站关键词优化怎么弄
  • 建设信用卡银行商城网站搜索引擎优化的基本手段
  • 阳江做网站多少钱网站建设网站推广
  • 做微信广告网站有哪些内容seo入门视频
  • 怎么根据街景图片找地址seo是指搜索引擎营销
  • 河南网站建站系统平台爱站网seo
  • python基础教程雪峰seo整站优化报价
  • 重庆南川网站制作公司推荐晨阳seo服务
  • 摄影做网站百度联盟是什么
  • 东坑东莞微信网站建设app开发公司排行榜
  • 帮妈妈做家务作文网站影响seo排名的因素
  • 怎样免费创建网站推广下载app拿佣金
  • 政府网站建设滞后微信营销平台有哪些
  • wordpress会员认证谷歌seo课程
  • 做魔杖网站seo建站教学
  • 通达oa 做网站网络广告推广公司
  • mugeda做网站张家界网站seo
  • 网站建设公司官网seo是什么的
  • 帮人做分销网站违法么网络推广工作好吗