对Spring源码的学习:基于XML文件配置的开发流程

目录

BeanFactory开发流程

ApplicationContext

BeanFactory与ApplicationContext对比

基于XML方式的Bean的配置

自动装配


BeanFactory开发流程

这里的第三方指的是Spring提供的BeanFactory,Spring启动时会初始化BeanFactory,然后读取配置清单(xml文件)获取需要被加载的bean。实现上面流程图的具体代码如下

创建beans.xml文件

public class Test {
    public static void main(String[] args) {
        //定义出一个bean工厂
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //读取xml文件的读取器
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        //读取配置文件
        reader.loadBeanDefinitions("beans.xml");
        UserService userService = (UserService) beanFactory.getBean("userService");
        System.out.println(userService);
    }
}

因为我们在开发中要遵循三层架构,业务层需要定义数据层,那么接下来我们再在xml文件中指定要一个数据层bean。代码如下

public class UserServiceImpl implements UserService {
    //该方法由beanFactory来调用,set注入
    public void setUserDao(UserDao userDao){
        System.out.println("由bean工厂调用该set方法");
    }
}

需要注意的是,需要property标签中的属性的name应该是setXxx()方法中的Xxx第一个子母小写之后的字符,ref标签指的是bean定义的id。接下来我们查看Test类的运行结果

public class Test {
    public static void main(String[] args) {
        //定义出一个bean工厂
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //读取xml文件的读取器
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        //读取配置文件
        reader.loadBeanDefinitions("beans.xml");
        UserService userService = (UserService) beanFactory.getBean("userService");
    }
}

执行结果截图 

BeanFactory是Spring中最重要的核心类,下文中的ApplicationContext虽然叫做Spring容器,但实际上在该类中最后调用的还是BeanFactory。

ApplicationContext

ApplicationContext称为Spring容器,内部封装了BeanFactory,比BeanFactory功能更丰富,使用ApplicationContext时,xml文件配置我们习惯叫做applicationContext.xml。接下来是一个示例代码

public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Object userService = context.getBean("userService");
    }
}

BeanFactory与ApplicationContext对比

  1. BeanFactory是Spring的早期接口,称为Spring的Bean工厂,ApplicationContext是后期更高级接口,称之为Spring 容器
  2. ApplicationContext在BeanFactory基础上对功能进行了扩展,例如: 监听功能、国际化功能等。BeanFactory的API更偏向底层,ApplicationContext的API大多数是对这些底层API的封装;
  3. Bean创建的主要逻辑和功能都被封装在BeanFactory中ApplicationContext不仅继承了BeanFactory,而且ApplicationContext内部还维护着BeanFactory的引用,所以,ApplicationContext与BeanFactory既有继承关系,又有融合关系。
  4. Bean的初始化时机不同,原始BeanFactory是在首次调用getBean时才进行Bean的创建,而ApplicationContext则是配置文件加载,容器一创建就将Bean都实例化并初始化好

基于XML方式的Bean的配置

XmI配置方式

功能描述

<bean id="class="">

Bean的id和全限定名配置

<bean name="">

通过name设置Bean的别名,通过别名也能直接获取到Bean实例

<bean scope="">

Bean的作用范围,BeanFactory作为容器时取值singleton和prototype

<bean lazy-init="">

Bean的实例化时机,是否延迟加载。BeanFactory作为容器时无效

<bean init-method="">

Bean实例化后自动执行的初始化方法,method指定方法名

<bean destroy-method="">

Bean实例销毁前的方法,method指定方法名

<bean autowire="byType">

设置自动注入模式,常用的有按照类型byType,按照名字byName

<bean factory-bean="" factory-method=""/>

指定哪个工厂Bean的哪个方法完成Bean的创建

默认情况下,单纯的Spring环境的Bean的作用范围有两个:Singleton与Prototype

  • Singleton:单例,默认值,Spring容器创建的时候,就会进行Bean的实例化,并存储到容器内部的单例池中,每次getBean时都是从单例池中获取相同的Bean实例。
  • Prototype:原型,Spring容器初始化时不会创建Bean实例,当调用getBean时才会实例化Bean,每次getBean都会创建一个新的Bean实例。

Spring实例化Bean的两种方式如下:

一:通过构造方法实例化

默认在xml文件中配置的信息都是调用了无参构造器,但是如果我们需要参数时,需要添加constructor-arg标签,该标签标识向方法中传递参数。

<beans>
  <bean id="userService" class="com.zmt.service.impl.UserServiceImpl">
    <!-- 默认采用无参构造器,但如果需要参数,则需要进行配置 -->
    <constructor-arg name="参数名称" value="参数值"></constructor-arg>
    <property name="userDao" ref="userDao"></property>
  </bean>
  <bean id="userDao" class="com.zmt.dao.impl.UserDaoImpl"></bean>
</beans>

二:通过调用自定义的工厂方法对Bean进行实例化

静态工厂方法实例化Bean

public class MyBeanFactory {
    public static UserDao getUserDao(){
        //在实例化Bean之前,我们可以进行一些业务逻辑操作
        return new UserDaoImpl();
    }
}
  <beans>
      <!--指定执行自定义的Bean工厂的指定方法去实例化Bean-->
      <bean id="userDao1" class="com.zmt.factory.MyBeanFactory" factory-method="getUserDao"></bean>

      <bean id="userService" class="com.zmt.service.impl.UserServiceImpl">
          <property name="userDao" ref="userDao"></property>
      </bean>
      <bean id="userDao" class="com.zmt.dao.impl.UserDaoImpl"></bean>
  </beans>

可以看到执行结果,一个是通过无参构造器创建出来的Bean一个是通过自定义的静态工厂创建的。

实例工厂方法实例化Bean

与静态工厂方法实例化Bean区别在于,我们需要将工厂类也加载为Bean对象,然后通过该Bean对象去实例化

public class MyBeanFactory1 {
    public UserDao getUserDao(){
        //在实例化Bean之前,我们可以进行一些业务逻辑操作
        return new UserDaoImpl();
    }
}
<beans>
  <!--加载工厂Bean-->
  <bean id="myBeanFactory1" class="com.zmt.factory.MyBeanFactory1"></bean>
  <!--通过工厂Bean去获取需要的对象-->
  <bean id="userDao2" factory-bean="myBeanFactory1" factory-method="getUserDao"></bean>
  <!--指定执行自定义的Bean工厂的指定方法去实例化Bean-->
  <bean id="userDao1" class="com.zmt.factory.MyBeanFactory" factory-method="getUserDao"></bean>

  <bean id="userService" class="com.zmt.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
  </bean>
  <bean id="userDao" class="com.zmt.dao.impl.UserDaoImpl"></bean>
</beans>

实现FactoryBean规范延迟实例化Bean

//需要指定FactoryBean的泛型
public class MyBeanFactory2 implements FactoryBean<UserDao> {
    //该方法在执行getBean的时候去执行
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    //获取该Bean工厂产生的Bean类型
    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }
}
  <beans>
      <!--Bean名称是userDao3,但加载的是工厂类-->
      <bean id="userDao3" class="com.zmt.factory.MyBeanFactory2"></bean>

      <!--加载工厂Bean-->
      <bean id="myBeanFactory1" class="com.zmt.factory.MyBeanFactory1"></bean>
      <!--通过工厂Bean去获取需要的对象-->
      <bean id="userDao2" factory-bean="myBeanFactory1" factory-method="getUserDao"></bean>
      <!--指定执行自定义的Bean工厂的指定方法去实例化Bean-->
      <bean id="userDao1" class="com.zmt.factory.MyBeanFactory" factory-method="getUserDao"></bean>

      <bean id="userService" class="com.zmt.service.impl.UserServiceImpl">
          <property name="userDao" ref="userDao"></property>
      </bean>
      <bean id="userDao" class="com.zmt.dao.impl.UserDaoImpl"></bean>
  </beans>

延迟加载Bean实际上是先加载了工厂Bean类,当需要用到Bean时,会从单例池中获取FactoryBean后调用该对象中的getObject()方法获取到真正的的Bean对象,并将该Bean对象缓存在factoryBeanObjectCache中,当使用到该Bean对象时从该Map中获取。

自动装配

我们通过编写property标签进行的注入叫做手动注入,而自动装配是不需要编写property标签的,而是在bean标签中使用autowire属性来实现自动注入,aotuwire的值有两个:byName、byType

  • byName:通过属性名自动装配,去匹配setXxx与id="xxx"是否一致
  • byType:通过Bean的类型从容器中匹配,匹配出多个相同Bean类型时,报错

UserServiceImpl存在一个setUserDao方法,因此我们可以这么编写,同样可以将属性注入到UserServiceImpl中

<beans>
    <bean id="userService" class="com.zmt.service.impl.UserServiceImpl" autowire="byName"></bean>
    <bean id="userDao" class="com.zmt.dao.impl.UserDaoImpl"></bean>
</beans>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/240945.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[山东大学操作系统课程设计]实验六

0.写在前面&#xff1a; 事先说明一点&#xff0c;在实验六开始&#xff0c;绝大多数的问题我应该都无法解释了&#xff0c;因为我自己做这个实验都是有点困难的&#xff0c;所以在接下来我不会过多阐述原理上的东西&#xff0c;只交待这个东西是怎么做的。 另外实验六七又是…

关于“Python”的核心知识点整理大全17

目录 ​编辑 8.3.4 结合使用函数和 while 循环 greeter.py 8.4 传递列表 greet_users.py 8.4.1 在函数中修改列表 printing_models.py 8.4.2 禁止函数修改列表 要将列表的副本传递给函数&#xff0c;可以像下面这样做&#xff1a; 往期快速传送门&#x1f446;&#x…

java SSM教师工作量管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 教师工作量管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要…

【数学建模】《实战数学建模:例题与讲解》第十二讲-因子分析、判别分析(含Matlab代码)

【数学建模】《实战数学建模&#xff1a;例题与讲解》第十二讲-因子分析、判别分析&#xff08;含Matlab代码&#xff09; 基本概念时间判别费歇判别贝叶斯判别 习题10.31. 题目要求2.解题过程3.程序4.结果 习题10.6&#xff08;1&#xff09;1. 题目要求2.解题过程——对应分析…

OLED屏幕,如何成为商显主流

OLED屏幕在商显领域的应用逐渐增加&#xff0c;成为商显主流的原因主要有以下几点&#xff1a; 显示效果优异&#xff1a;OLED屏幕具有自发光原理&#xff0c;色彩鲜艳、对比度高、视角广&#xff0c;能够提供更好的视觉体验。在商业展示、广告宣传等场景中&#xff0c;OLED屏幕…

Feign-自定义配置

目录 一、自定义Feign配置 二、修改日志级别 方式一&#xff1a;application配置文件方式 方式二&#xff1a;java代码方式 三、总结 一、自定义Feign配置 二、修改日志级别 配置Feign日志有两种方式 方式一&#xff1a;application配置文件方式 &#xff08;1&#xff09…

Java服务占用过高CPU排查思路

一、背景说明 如果线上启动的Java服务占用过高的CPU&#xff0c;我们通过top命令是可以查看到的。 那么问题来了&#xff0c;如果通过top命令查看到是因为java服务引起的占用过高的CPU时间&#xff0c;该如何进行详细的排查呢&#xff1f;换句话说就是如何定位问题发生在代码的…

Vue中使用echarts@4.x中国地图及AMap相关API的使用

一、此 demo 实现的基本功能 1.中国地图的显示 2.地图点击下钻的功能 3.地图相关组件的使用&#xff0c;例 tooltip… 二、实现思路 初始使用下载本地的中国 geo 格式的 json 数据来绘制地图&#xff0c;点击某一区划&#xff08;例&#xff1a;山东省&#xff09;时&#xff0…

PySpark大数据处理详细教程

欢迎各位数据爱好者&#xff01;今天&#xff0c;我很高兴与您分享我的最新博客&#xff0c;专注于探索 PySpark DataFrame 的强大功能。无论您是刚入门的数据分析师&#xff0c;还是寻求深入了解大数据技术的专业人士&#xff0c;这里都有丰富的知识和实用的技巧等着您。让我们…

Centos7 配置Git

随笔记录 目录 1&#xff0c; 新建用户 2. 给用户设置密码相关操作 3. 为新用户添加sudo 权限 4. 配置Git 4.1 配置Git 4.2 查看id_ras.pub 5, 登录Git 配置SSH 秘钥 6. Centos7 登录Git 7. clone 指定branch到本地 8. 将新代码复制到指定路径 9. 上传指定代码 …

2023年11月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2023年11月国产数据库大事件和重要产品发布消息。 11月国产数据库大事记 TOP10 11月国产数据库大事记&#xff08;时间线&#xff09; 11月1日消息&#xff0c;近日&#xff0c;由金仓数据库支撑的某大型运营商B域一级BOSS枢纽系统顺利升级上线。金仓数…

四川技能大赛——2023年四川网信人才技能大赛(网络安全管理员赛项)决赛

四川技能大赛——2023年四川网信人才技能大赛&#xff08;网络安全管理员赛项&#xff09;决赛 文章目录 四川技能大赛——2023年四川网信人才技能大赛&#xff08;网络安全管理员赛项&#xff09;决赛C1-比64少的bas - DONEC2-affine - DONEC3-简单的RSA - DONEM1-不要动我的f…

关于String.Format混合$符号格式化引发的问题

之前一个老项目是用string.Format()进行格式化的&#xff0c;.net 4.5之后的版本 引入 $"字符串" 格式化标识符&#xff0c; 如下代码&#xff1a; string barcode "1234567{#0.000}ABCDE";barcode "12345START{0:#000}ABCDE";try{string sFo…

【网络安全技术】电子邮件安全PGP,SMIME

一、PGP&#xff08;Pretty Good Privacy&#xff09; PGP是一种邮件加密手段&#xff0c;他在发邮件一方加密&#xff0c;然后发给发送方邮件服务器&#xff0c;发送方邮件服务器再发送给接收方邮件服务器&#xff0c;然后接收方再从接收方邮件服务器pop出来&#xff0c;这整…

vue实现自动打字效果(带光标效果)

代码介绍(其实就是通过字符串截取加定时拼接完成的,我相信有时间都能琢磨出来,来这里就是为了省事) 上vue页面代码: <template><div idApp><h2>{{text}}<span ref"fou" class"fousdis">{{_}}</span></h2></div>…

CentOS 7 部署frp穿透内网

本文将介绍如何在CentOS 7.9上部署frp&#xff0c;并通过示例展示如何配置和测试内网穿透。 文章目录 &#xff08;1&#xff09;引言&#xff08;2&#xff09;准备工作&#xff08;4&#xff09;frps服务器端配置&#xff08;5&#xff09;frpc客户端配置&#xff08;6&#…

工信部举行发布会 数字化产业推动元宇宙发展取得良好成效

据官方消息&#xff0c;工业和信息化部12日举行“发挥国家高新区作用 加快推进新型工业化”新闻发布会。 在数字化建设方面取得了良好的成绩&#xff1a; 一是数字经济加速发展。国家高新区着力推动人工智能、大数据、云计算、区块链和元宇宙等新产业新业态蓬勃发展&#xff…

1688订单详情接口使用指南:含代码实现获取订单信息

一、引言 随着电子商务的飞速发展&#xff0c;越来越多的企业开始通过1688平台进行采购和销售。为了更好地管理订单&#xff0c;提高客户满意度&#xff0c;许多企业选择使用1688订单详情接口来获取订单信息。本文将详细介绍如何使用1688订单详情接口&#xff0c;并提供示例代…

2023 年山东省职业院校技能大赛(高等职业教育) “信息安全管理与评估”样题

2023 年山东省职业院校技能大赛&#xff08;高等职业教育&#xff09; “信息安全管理与评估”样题 目录 任务 1 网络平台搭建&#xff08;50 分&#xff09; 任务 2 网络安全设备配置与防护&#xff08;250 分&#xff09; 模块二 网络安全事件响应、数字取证调查、应用程序安…

Guava的注解处理机制

第1章&#xff1a;引言 Guava不仅仅是一个工具库&#xff0c;它更像是Java程序员的瑞士军刀&#xff0c;提供了一系列强大的功能&#xff0c;从集合操作到函数式编程&#xff0c;再到今天咱们要深入探讨的——注解处理机制。 注解&#xff08;Annotations&#xff09;&#x…