0


【Spring】1、Spring 框架的基本使用【读取配置文件、IoC、依赖注入的几种方式、FactoryBean】

目录

一、Spring 简介

在这里插入图片描述

  • Spring makes Java Simple、modern、productive …

Spring 框架的几个核心概念:

IoC: Inversion of Control:控制反转

DI: Dependency Injection:依赖注入

AOP: Aspect Oriented Programming:面向切面编程

Object Oriented Programming: 面向对象编程

这里使用的 Spring 的版本是:5.2.8.release

🚀耦合:我依赖你,你不见了(不要你了),对我影响很大,我就得改代码

🚀写代码的方向:解耦,降低耦合性

二、读取配置文件、创建对象

①🎄 通过类加载器读取配置文件的输入流
②🎄 通过

Properties

对象的

load()

方法,传入输入流【加载配置文件】
③🎄 通过

Properties

对象的

getProperty(String key)

方法获取到 key 对应的 value
④🎄 使用反射 API,通过全类名创建类的实例

/**
 * 创建对象实例的工厂
 */publicclassInstanceFactory{// Properties 对象表示【.properties】配置文件privatestaticProperties properties;static{// 获取配置文件的输入流try(InputStream is =InstanceFactory.class.getClassLoader().getResourceAsStream("properties.properties")){
            properties =newProperties();// 加载配置文件输入流
            properties.load(is);}catch(Exception e){
            e.printStackTrace();}}privatestaticObjectAblegetObjectByName(String key){// 获取配置文件内容String fullPath = properties.getProperty(key);try{Class<?> cls =Class.forName(fullPath);return(ObjectAble) cls.newInstance();}catch(Exception e){
            e.printStackTrace();}returnnull;}publicstaticObjectAblecreate(String key){returngetObjectByName(key);}}
properties.properties 配置文件
personFullPath=com.guoqing.po.PersonV2
dogFullPath=com.guoqing.po.DogV2
boyFullPath=com.guoqing.po.Boy

🎄工厂模式结合配置文件降低类之间的耦合
🎄Spring 的 IoC 就是一个大工厂

三、使用 Spring

(1) 依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.8.RELEASE</version></dependency>

(2) Spring 的核心配置文件

  • 按照下图所示创建 applicationContext.xml 文件(Spring 的核心配置文件)在这里插入图片描述在这里插入图片描述
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 【bean】所有被 Spring 管理的对象都是 bean --><!-- 配置需要被 Spring 管理的类 --><!-- id: 可通过 id 的值获取到该类的实例 --><!-- class: 该类的全类名 --><beanid="boy"class="com.guoqing.po.Boy"/><beanid="personV1"class="com.guoqing.po.PersonV1"/><beanid="personV2"class="com.guoqing.po.PersonV2"/></beans>

(3) 获取 Spring IoC 工厂中的对象实例

类路径的东西:
① java 文件夹中的东西(打包后

classes

中的内容)
② resources 文件夹中的东西
在这里插入图片描述

publicclassQQMain{publicstaticvoidmain(String[] args){// 读取 Spring 的核心配置文件, 并得到 Spring 的 IoC 工厂ClassPathXmlApplicationContext ctx =newClassPathXmlApplicationContext("applicationContext.xml");// 通过 IoC 工厂获取实例(boy 是 Spring 的核心配置文件中的 bean 标签的 id 属性配置的内容)Boy boy = ctx.getBean("boy",Boy.class);System.out.println("boy = "+ boy);}}

🍃 读取配置文件,并返回 IoC 容器的类是:ClassPathXmlApplicationContext
🍃 调用 ClassPathXmlApplicationContext 对象的

getBean()

方法,传入 bean 标签的 id 值 获取对象实例

属性的本质含义是:

set 方法

后面的值改为小写

setName()

name 就是属性】

setBoySchool()

boySchool 就是属性】

  • IoC 最重要的作用:解耦合
  • Spring 可以轻松整合日志框架
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency>

通过

logback-classic

框架可以看到 Spring 相关的日志信息

在这里插入图片描述

四、IoC 容器

  • IoC:Inversion of Control【控制反转】
  • 对象创建的控制权转交给了 Spring
  • IoC 容器创建了一系列的 bean
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="bookDaoImpl"class="com.guoqing.dao.impl.BookDaoImpl"/><beanid="bookServiceImpl"class="com.guoqing.service.impl.BookServiceImpl"><propertyname="bookDao"ref="bookDaoImpl"/></bean><beanid="bookController"class="com.guoqing.controller.BookController"><propertyname="bookService"ref="bookServiceImpl"/></bean></beans>

五、依赖注入(DI)

  • 依赖注入:Dependency Injection

常见的注入类型有3大类:
① bean(自定义类型)【

ref 属性


② 基本类型、String、BigDecimal、包装类型【

value

属性】
③ 集合类型(数组、Map、List、Set、Properties)☆


常见的注入方式有 2 种:
① 基于 setter(属性)
② 基于 constructor (构造方法)

(1) 基于 setter 注入【bean】

在这里插入图片描述

<beanid="cat"class="com.guoqing.domain.Cat"><propertyname="catName"value="哆啦A梦"/><propertyname="color"value="BLUE"/></bean><beanid="person"class="com.guoqing.domain.Person"><propertyname="cat"ref="cat"/></bean>
<beanid="cat"class="com.guoqing.domain.Cat"><propertyname="catName"value="哆啦A梦"/><propertyname="color"value="BLUE"/></bean><beanid="person"class="com.guoqing.domain.Person"><propertyname="cat"><refbean="cat"/></property></bean>
<beanid="girl"class="com.guoqing.domain.Girl"><propertyname="cat"><beanclass="com.guoqing.domain.Cat"><propertyname="catName"value="卡菲"/><propertyname="color"value="PINK"/></bean></property></bean>

(2) 基于 setter 注入【基本类型、包装类型、String、BigDecimal】

<beanid="person"class="com.guoqing.domain.Person"><propertyname="id"value="666"/><propertyname="name"><value>张国庆</value></property><propertyname="age"value="8"/><propertyname="money"><value>88888.666</value></property></bean>

(3) 基于 setter 注入【集合类型】

  • 🍃 注入数组在这里插入图片描述
<beanid="whatever"class="com.guoqing.domain.Whatever"><propertyname="books"><array><value>Java 编程思想</value><value>红楼梦</value><value>水浒传</value><value>三国演义</value><value>三体</value></array></property><propertyname="cats"><array><beanclass="com.guoqing.domain.Cat"><propertyname="color"value="RED"/><propertyname="catName"value="小红"/></bean><beanclass="com.guoqing.domain.Cat"><propertyname="color"value="BLACK"/><propertyname="catName"value="小黑"/></bean></array></property></bean>
  • 🍃 注入 List在这里插入图片描述
<beanid="whatever"class="com.guoqing.domain.Whatever"><propertyname="books"><!-- ArrayList --><list><value>Thinking In Java</value><value>红楼梦</value><value>水浒传</value><value>三国演义</value><value>三体</value></list></property><propertyname="cats"><list><beanclass="com.guoqing.domain.Cat"><propertyname="color"value="RED"/><propertyname="catName"value="小红"/></bean><beanclass="com.guoqing.domain.Cat"><propertyname="color"value="BLACK"/><propertyname="catName"value="小黑黑"/></bean></list></property></bean>
  • 🍃 注入 Set

在这里插入图片描述

<beanid="whatever"class="com.guoqing.domain.Whatever"><propertyname="goods"><!--LinkedHashSet--><set><value>苹果1</value><value>土豆2</value><value>西瓜3</value><value>电脑4</value><value>窗户5</value><value>窗户5</value><value>窗户5</value><value>鼠标6</value></set></property></bean>

在这里插入图片描述

HashSet 是无顺序的【可去重】
LinkedHashSet 是有顺序的【可去重】

  • 🍃 注入 Map

在这里插入图片描述

<beanid="whatever"class="com.guoqing.domain.Whatever"><propertyname="peoSal"><map><entrykey="张国庆"value="88888"/><entrykey="周杰伦"value="155555"/><entrykey="王凡"value="266666"/><entrykey="陈铭酒"value="12121"/><entrykey="刘德华"value="888888"/></map></property><propertyname="peoCatMap"><map><entrykey="ZGQ"><beanclass="com.guoqing.domain.Cat"><propertyname="catName"value="猫猫1"/><propertyname="color"value="RED"/></bean></entry><entrykey="CMJ"><beanclass="com.guoqing.domain.Cat"><propertyname="catName"value="猫猫2"/><propertyname="color"value="PINK"/></bean></entry></map></property></bean>
  • 🍃 注入 Properties
<beanid="whatever"class="com.guoqing.domain.Whatever"><propertyname="properties"><props><propkey="dao">com.guoqing.dao.impl.BookDaoImpl</prop><propkey="service">com.guoqing.service.impl.BookServiceImpl</prop></props></property></bean>

基于 setter 注入调用的是无参的构造方法

(4) 基于 setter 注入(命名空间)

在这里插入图片描述

没有命名空间的写法: 
<beanid="cat"class="com.guoqing.domain.Cat"><propertyname="color"value="skyblue"/><propertyname="catName"value="阿辉"/></bean><beanid="teacher"class="com.guoqing.domain.Teacher"><propertyname="id"value="2"/><propertyname="name"value="李老师"/><propertyname="salary"value="12121.666"/><propertyname="gender"value="男"/><propertyname="cat"ref="cat"/></bean>

命名空间写法:

增加命名空间:

xmlns:p="http://www.springframework.org/schema/p"
<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><beanid="cat"class="com.guoqing.domain.Cat"p:catName="阿辉辉"p:color="SKYBLUE"/><beanid="teacher"p:name="张国庆老师"p:id="22"p:salary="6666.666"p:gender="男"p:cat-ref="cat"class="com.guoqing.domain.Teacher"/></beans>

(5) 基于构造方法注入

  • 基本类型在这里插入图片描述
<!--调用没有参数的构造方法--><beanid="student"class="com.guoqing.domain.Student"/>
<beanid="student"class="com.guoqing.domain.Student"><!--调用有一个参数的构造方法--><constructor-argvalue="张国庆"/></bean>
<beanid="student"class="com.guoqing.domain.Student"><!--调用有2个参数的构造方法--><constructor-argvalue="张国庆"/><constructor-argvalue="99.5"/></bean>
<beanid="student"class="com.guoqing.domain.Student"><!--假如顺序和构造方法参数的顺序不一样的话, 可以指定 type--><!--若不顺序不一样, 且不做任何处理, 必定报错--><constructor-argvalue="99.5"type="double"/><constructor-argvalue="张国庆"type="java.lang.String"/></bean>
<beanid="student"class="com.guoqing.domain.Student"><!--假如顺序和构造方法参数的顺序不一样的话, 可以指定 index--><!--若不顺序不一样, 且不做任何处理, 必定报错--><constructor-argvalue="99.5"index="1"/><constructor-argvalue="张国庆"index="0"/></bean>

  • bean 注入

在这里插入图片描述

<beanid="student"class="com.guoqing.domain.Student"><constructor-argvalue="张国庆"index="0"/><constructor-arg><beanclass="com.guoqing.domain.Cat"><propertyname="catName"value="花儿"/><propertyname="color"value="ORANGE"/></bean></constructor-arg></bean>
<beanid="cat"class="com.guoqing.domain.Cat"><propertyname="catName"value="流浪猫"/><propertyname="color"value="GRAY"/></bean><beanid="student"class="com.guoqing.domain.Student"><constructor-argvalue="张国庆"index="0"/><constructor-argref="cat"/></bean>
<beanid="cat"class="com.guoqing.domain.Cat"><propertyname="catName"value="流浪猫"/><propertyname="color"value="GRAY"/></bean><beanid="student"class="com.guoqing.domain.Student"><constructor-argvalue="张国庆"index="0"/><constructor-arg><refbean="cat"/></constructor-arg></bean>

  • 注入集合
<beanid="student"class="com.guoqing.domain.Student"><constructor-argtype="java.util.List"><list><value>语文</value><value>数学</value><value>英语</value><value>物理</value><value>化学</value></list></constructor-arg></bean>

六、创建过程比较复杂的对象

🥄 Spring 的配置文件中配置的对象只需要执行某些构造方法即可创建
🥄 当遇到创建过程极其复杂的对象(无法通过调用构造方法创建的对象)时就需要下面的方式了
🥄 如:JDBC 的 Connection 对象的创建

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.19</version></dependency>

(1) 静态工厂(调用静态方法)

publicclassJdbcConnectionFactory{/**
     * 静态工厂
     */publicstaticConnectiongetConnection()throwsException{Class.forName("com.mysql.cj.jdbc.Driver");returnDriverManager.getConnection("jdbc:mysql://localhost:3306/jump_zgq?serverTimezone=UTC","root","root");}}
<beanid="jdbcConnection"class="com.guoqing.factory.JdbcConnectionFactory"factory-method="getConnection"/>

🎀把创建复杂对象代码写在工厂中
🎀通过该工厂中的 static 方法返回对象的实例
🎀在 Spring 的核心配置文件中,通过

factory-method

属性指定需要调用该工厂类的哪个方法返回对象实例
🎀【缺点】无法传参

(2) 实例工厂

publicclassJdbcConnectionFactory{privateString driverClass;privateString url;privateString user;privateString pwd;publicJdbcConnectionFactory(String driverClass,String url,String user,String pwd){this.driverClass = driverClass;this.url = url;this.user = user;this.pwd = pwd;}/**
     * 实例工厂
     */publicConnectiongetConnection()throwsException{System.out.println("调用了 getConnection() 方法");Class.forName(this.driverClass);returnDriverManager.getConnection(url, user, pwd);}}
<!--创建工厂实例--><beanid="jdbcConnectionFactory"class="com.guoqing.factory.JdbcConnectionFactory"><constructor-argname="driverClass"value="com.mysql.cj.jdbc.Driver"/><constructor-argname="url"value="jdbc:mysql://localhost:3306/jump_zgq?serverTimezone=UTC"/><constructor-argname="user"value="root"/><constructor-argname="pwd"value="root"/></bean><!--通过工厂实例创建 Connection 对象--><beanid="jdbcConnection"factory-bean="jdbcConnectionFactory"factory-method="getConnection"/>

🎉

factory-bean

属性指代工厂类的实例
🎉

factory-method

属性指代要调用工厂对象的哪个实例方法来返回该复杂对象

(3) FactoryBean

🎁 Spring 提供的、用于方便地创建复杂对象的接口
🎁 本质和【实例工厂】类似

publicclassJdbcConnectionFactoryBeanimplementsFactoryBean<Connection>{privateString driverClass;privateString url;privateString user;privateString pwd;publicJdbcConnectionFactoryBean(String driverClass,String url,String user,String pwd){this.driverClass = driverClass;this.url = url;this.user = user;this.pwd = pwd;}/**
     * 写创建该复杂对象的一系列代码
     */@OverridepublicConnectiongetObject()throwsException{System.out.println("调用了 getObject() 方法");Class.forName(this.driverClass);returnDriverManager.getConnection(url, user, pwd);}@OverridepublicClass<?>getObjectType(){returnConnection.class;}}
<beanid="jdbcConnection"class="com.guoqing.factoryBean.JdbcConnectionFactoryBean"><constructor-argname="driverClass"value="com.mysql.cj.jdbc.Driver"/><constructor-argname="url"value="jdbc:mysql://localhost:3306/jump_zgq?serverTimezone=UTC"/><constructor-argname="user"value="root"/><constructor-argname="pwd"value="root"/></bean>

🍃 监听

class

属性后的是否实现(implements)了FactoryBean 接口
🍃 若实现了 FactoryBean 接口,则调用该

getObject()

方法,然后将该方法返回的实例放入 IoC 容器中

若就是想拿到该类的实例,可通过

&

符号拼接上 id 属性的值,然后通过

getBean()

方法获取

publicclassQQMain{publicstaticvoidmain(String[] args){ApplicationContext ctx =newClassPathXmlApplicationContext("applicationContext.xml");Object bean = ctx.getBean("&jdbcConnection");// bean = com.guoqing.factoryBean.JdbcConnectionFactoryBean@436e852bSystem.out.println("bean = "+ bean);}}

若文章有错误请不吝赐教

标签: spring java 后端

本文转载自: https://blog.csdn.net/m0_54189068/article/details/131243060
版权归原作者 JavaLearnerZGQ 所有, 如有侵权,请联系我们删除。

“【Spring】1、Spring 框架的基本使用【读取配置文件、IoC、依赖注入的几种方式、FactoryBean】”的评论:

还没有评论