77百科网
当前位置: 首页 生活百科

spring框架学习(一篇文章带你掌握主流基础框架)

时间:2023-06-06 作者: 小编 阅读量: 1 栏目名: 生活百科

数据库事务的一般化抽象层,允许插件式事务管理器,简化事务的划分使之与底层无关。一个可用于从applet到JavaEE等不同运行环境的核心Bean工厂。

这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容

那么简单说明一下Spring的必要性:

  • Spring技术是JavaEE开发的必备技能,企业开发技术选型率高达90%!
  • Spring可以帮助简化开发,降低企业级开发的复杂度
  • Spring可以进行框架整合,高效整合其他技术,提高企业级应用开发与运行效率

Spring的核心内容:

  • Ioc技术
  • DI技术
  • AOP
  • 事务处理

Spring可进行的框架整合:

  • MaBatis
  • MyBatis-plus
  • Struts
  • Struts2
  • Hibernate

在接下来的文章中,我们会学习Spring的框架思想,学习Spring的基本操作,结合案例熟练掌握

温馨提醒:在学习本篇文章前请先学习JavaWeb相关内容

(HTTP,Tomcat,Servlet,Request,Response,MVC,Cookie,Session,Ajax,Vue等内容)

初识Spring

官网:Spring | Home

Spring发展至今已经形成了一套开发的生态圈,Spring提供了相当多的项目,每个项目用于完成特定功能

我们常用的主流技术包括有:

  • Spring Framework:Spring框架
  • Spring Boot:Spring简化代码开发
  • Spring Cloud:Spring分布设计
Spring FrameWork系统架构

在系统学习Spring之前,我们需要先来了解FrameWork系统结构

  • Spring FrameWork是Spring生态圈中最基本的项目,是其他项目的根基

我们现在所使用的Spring FrameWork是4.0版本,已经趋于稳定

下面我们对架构图进行解释:

  • Core Container:核心容器
  • AOP:面向切面编程
  • Aspects:AOP思想实现
  • Data Access:数据访问
  • Data Intergration:数据集成
  • Web:Web开发
  • Test:单元测试与集成测试

我们可以在官方中获得如此评价:

  • 强大的基于 JavaBeans 的采用控制反转(Inversion of Control,IoC)原则的配置管理,使得应用程序的组建更加快捷简易。
  • 数据库事务的一般化抽象层,允许插件式事务管理器,简化事务的划分使之与底层无关。
  • 一个可用于从 applet 到 Java EE 等不同运行环境的核心 Bean 工厂。
核心概念介绍

首先我们思索一下我们之前的业务层与数据层:

// 数据层接口public interface BookDao {public void save();}

// 数据层实现public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}

// 业务层接口public interface BookService {public void save();}

// 业务层实现public class BookServiceImpl implements BookService {private BookDao bookDao;public void save() {bookDao.save();}}

如果我们修改BookDaoImpl内容,那么相对应的业务层实现中的bookDao的new实现也要进行修改,甚至下方方法的对象也要进行修改

Spring使用前问题

代码书写现状:

  • 耦合度偏高

解放方案:

  • 使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象
Spring思想以及实现

IoC(Inversion of Control)控制反转思想:

  • 使用对象时,由主动new创建对象转换为由外部提供对象
  • 此过程中对象创建控制权由程序转移到外部,被称为控制反转

DI(Dependency Injection)依赖注入:

  • 在容器中建立Bean与Bean之间的依赖关系和整个过程,被称为依赖注入

Spring技术对Ioc思想进行了实现:

  • Spring提供了一个容器,被称为Ioc容器,用来充当IoC思想的外部
  • IoC容器负责对象的创建,初始化等一系列工作,被创建和管理的对象在IoC容器中被称为Bean

// 数据层实现public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}

// IoC容器/*包含daoservice两者可以建立连接*/

// 业务层实现public class BookServiceImpl implements BookService {private BookDao bookDao;public void save() {bookDao.save();}}

目的:充分解耦

  • IoC:使用IoC容器管理bean
  • DI:在IoC容器内将有依赖关系的bean进行关系绑定

最终效果:

  • 使用对象不仅可以直接从IoC容器中获取,还可以将已获得的Bean之间绑定依赖关系
IoC入门

首先我们需要明白IoC的使用规则:

  1. IoC负责管理什么:Service和Dao
  2. 如何被管理的对象告知IoC容器:(配置)
  3. 被管理的对象交给IoC容器,如何获得IoC容器:(接口)
  4. IoC容器得到之后,如何获得Bean:(接口方法)
  5. 使用Spring所需要导入的坐标:(pom.xml)

下面我们给出IoC入门的详细步骤:

  1. 创建Maven项目,在pom.xml中导入坐标

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

  1. 创建Spring.xml的配置包(applicationContext.xml,导入坐标后xml中更新该XML)

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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"><!--2.配置bean--><!--bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型(注意需要是实现类)--><bean/><bean/></beans>

  1. 主函数

package com.itheima;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class App2 {public static void main(String[] args) {//3.获取IoC容器ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//4.获取bean(根据bean配置id获取)//BookDao bookDao = (BookDao) ctx.getBean("bookDao");//bookDao.save();// 注意:需要类型转化BookService bookService = (BookService) ctx.getBean("bookService");bookService.save();}}

DI入门

首先我们需要明白DI的使用规则:

  1. 基于IoC管理bean
  2. Service中使用new形式创建Dao对象是否保留:(否)
  3. Service中需要Dao对象如何进入到Service中:(提供方法)
  4. Service与Dao之间的关系如何描述:(配置)

下面我们给出DI入门的详细步骤(基于IoC入门):

  1. 删除new方法

public class BookServiceImpl implements BookService {//5.删除业务层中使用new的方式创建的dao对象private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}}

  1. 创建对象的set方法

public class BookServiceImpl implements BookService {//5.删除业务层中使用new的方式创建的dao对象private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}//6.提供对应的set方法public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}}

  1. 创建Dao和Service的连接

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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"><!--2.配置bean--><!--bean标签标示配置beanid属性标示给bean起名字class属性表示给bean定义类型--><bean/><bean><!--7.配置server与dao的关系--><!--注意:在server中配置关系property标签表示配置当前bean的属性name属性表示配置哪一个具体的属性ref属性表示参照哪一个bean--><property name="bookDao" ref="bookDao"/></bean></beans>

Bean整体介绍

Bean是保存在IoC中的对象,我们通过配置的方式获得Bean

下面我们从三个方面分别讲解Bean:

bean基本配置

首先我们先介绍bean本身性质:

类别

描述

名称

bean

类型

标签

所属

beans标签

功能

定义Spring核心容器管理对象

格式

<beans><bean> </bean></beans>

属性列表

id:bean的id,使用容器可以通过id值获得对应的bean,在一个容器中id值唯一class:bean的类型,即配置的bean的全路径类名

范例

<bean>

然后我们介绍一下bean的别名:

类别

描述

名称

name

类型

标签

所属

bean标签

功能

定义bean的别名,可定义多个,使用逗号,分号,空格分隔

范例

<beanname="service service4 bookEbi" >

正常情况下,使用id和name都可以获得bean,但推荐还是使用唯一id

获得bean无论通过id还是name获取,如果无法找到则抛出异常NosuchBeanDefinitionException

最后我们介绍一下bean的作用范围scope:

类别

描述

名称

scope

类型

标签

所属

bean标签

功能

定义bean的作用范围,可选范围如下:singleton:单列(默认)prototype:非单列

范例

<beanname="dao"scope="prototype"/>

这里的scope指产生对象的数量

我们的scope在默认情况下是singleton,因为很多对象只需要创建一次,多次创建会导致内存膨胀

合适交给容器进行管理的bean(singleton):

表现层对象业务层对象数据层对象工具对象

不合适交给容器进行管理的bean(prototype):

封装实体的域对象(带有状态的bean)

bean实例化

bean的实例化通常分为四种方法,我们在下面一一介绍:

  1. 构造方法(常用)

我们需要在数据类中提供构造方法,配置条件中不需要改变

// 数据类public class BookDaoImpl implements BookDao {public BookDaoImpl() {System.out.println("book dao constructor is running ....");}public void save() {System.out.println("book dao save ...");}}

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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--><bean/></beans>

若无参构造方法不存在,则抛出异常BeanCreationException

  1. 静态工厂(了解)

我们在之前的案例中存在有对象工厂的说法,我们可以设置工厂并调用其方法得到bean

// 静态工厂package com.itheima.factory;import com.itheima.dao.OrderDao;import com.itheima.dao.impl.OrderDaoImpl;//静态工厂创建对象public class OrderDaoFactory {public static OrderDao getOrderDao(){System.out.println("factory setup....");return new OrderDaoImpl();}}

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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--><beanfactory-method="getOrderDao"/></beans>

  1. 实例工厂(了解)

和静态工厂相同,但不同点是方法不是静态,我们需要提前创建一个bean

// 实例工厂package com.itheima.factory;import com.itheima.dao.UserDao;import com.itheima.dao.impl.UserDaoImpl;//实例工厂创建对象public class UserDaoFactory {public UserDao getUserDao(){return new UserDaoImpl();}}

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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--><bean/><!--factory-bean:实例工厂本身beanfactory-method:使用调用bean的方法--><beanfactory-method="getUserDao" factory-bean="userFactory"/></beans>

  1. FactoryBean(重要实用)

除了我们之前自己定义的工厂外,Spring提供了一种官方版本的FactoryBean

// FactoryBean工厂(需接口,< >中填写数据类接口)package com.itheima.factory;import com.itheima.dao.UserDao;import com.itheima.dao.impl.UserDaoImpl;import org.springframework.beans.factory.FactoryBean;//FactoryBean创建对象public class UserDaoFactoryBean implements FactoryBean<UserDao> {//代替原始实例工厂中创建对象的方法// 返回创建对象类型为UserDaoImpl()public UserDao getObject() throws Exception {return new UserDaoImpl();}// 这里填写接口类型public Class<?> getObjectType() {return UserDao.class;}// 可以修改来修改其scope属性public boolean isSingleton() {return false;}}

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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"><!--方式四:使用FactoryBean实例化bean--><bean/></beans>

bean生命周期

我们先来接单介绍生命周期相关概念:

  • 生命周期:从创建到消亡的完整过程
  • bean生命周期:bean从创建到销毁的整体过程
  • bean生命周期控制:在bean创建后到销毁前做一些事情

接下来我们介绍生命周期控制方法:

  1. 数据层提供控制方法

由数据层提供方法,在xml配置文件中设置该方法

// 数据层package com.itheima.dao.impl;import com.itheima.dao.BookDao;public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}//表示bean初始化对应的操作public void init(){System.out.println("init...");}//表示bean销毁前对应的操作public void destory(){System.out.println("destory...");}}

<!--配置文件--><?xml version="1.0" encoding="UTF-8"?><beans xmlns="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"><!--init-method:设置bean初始化生命周期回调函数--><!--destroy-method:设置bean销毁生命周期回调函数,仅适用于单例对象--><beaninit-method="init" destroy-method="destory"/><bean><property name="bookDao" ref="bookDao"/></bean></beans>

  1. 接口控制方法(了解)

Spring为创建提供了两个接口,我们只需要继承并实现该方法即可

package com.itheima.service.impl;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.InitializingBean;// InitializingBean,DisposableBean 分别对应afterPropertiesSet,destroy方法,代表创建和销毁public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {private BookDao bookDao;public void setBookDao(BookDao bookDao) {System.out.println("set .....");this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}public void destroy() throws Exception {System.out.println("service destroy");}public void afterPropertiesSet() throws Exception {System.out.println("service init");}}

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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"><beaninit-method="init" destroy-method="destory"/><!--直接调用即可--><bean><property name="bookDao" ref="bookDao"/></bean></beans>

我们需要提及一下bean的销毁时机:(了解即可)

  • 因为默认情况下,我们的bean不会被销毁,因为虚拟机会直接退出,ClassPathXmlApplicationContext会被忽略销毁过程

所以如果我们希望销毁bean观察到destroy的实现,需要手动关闭:

  1. 手动关闭容器方法:

package com.itheima;import com.itheima.dao.BookDao;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class AppForLifeCycle {public static void main( String[] args ) {// 注意:这里需要采用ClassPathXmlApplicationContext作为对象,因为只有这个类才具有close方法ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();//关闭容器ctx.close();}}

  1. 注册关闭钩子,在虚拟机退出前先关闭容器再推出虚拟机

package com.itheima;import com.itheima.dao.BookDao;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class AppForLifeCycle {public static void main( String[] args ) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();//注册关闭钩子函数,在虚拟机退出之前回调此函数,关闭容器ctx.registerShutdownHook();}}

最后我们统计一下整体生命周期:

初始化容器:创建对象(分配内存)->执行构造方法->执行属性注入(set操作)->执行bean初始化方法使用bean:执行业务操作关闭/销毁容器:执行bean销毁方法

依赖注入方式

首先我们要知道类中传递数据的方法有两种:

  • 普通方法(Set方法)
  • 构造方法

然后我们要知道数据的类型大体分为两种:

  • 引入类型(数据层)
  • 简单类型(基本数据类型和String)

所以我们把依赖注入方式分为四种:

  • setter注入简单类型引用类型
  • 构造器注入简单类型引入类型
setter注入简单类型

首先我们需要在bean种定义简单类型属性并提供可以访问的set方法

package com.itheima.dao.impl;import com.itheima.dao.BookDao;public class BookDaoImpl implements BookDao {private String databaseName;private int connectionNum;//setter注入需要提供要注入对象的set方法public void setConnectionNum(int connectionNum) {this.connectionNum = connectionNum;}//setter注入需要提供要注入对象的set方法public void setDatabaseName(String databaseName) {this.databaseName = databaseName;}public void save() {System.out.println("book dao save ..." databaseName "," connectionNum);}}

然后在配置中使用property标签value属性注入简单类型数据

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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><!--property标签:设置注入属性--><!--name属性:设置注入的属性名,实际是set方法对应的名称--><!--value属性:设置注入简单类型数据值--><property name="connectionNum" value="100"/><property name="databaseName" value="mysql"/></bean></beans>

setter注入引用类型

首先我们需要在bean种定义引用类型属性并提供可以访问的set方法

package com.itheima.service.impl;import com.itheima.dao.BookDao;import com.itheima.dao.UserDao;import com.itheima.service.BookService;public class BookServiceImpl implements BookService{private BookDao bookDao;private UserDao userDao;//setter注入需要提供要注入对象的set方法public void setUserDao(UserDao userDao) {this.userDao = userDao;}//setter注入需要提供要注入对象的set方法public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();userDao.save();}}

然后在配置中使用property标签ref属性注入引用类型数据

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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><property name="connectionNum" value="100"/><property name="databaseName" value="mysql"/></bean><bean/><!--注入引用类型--><bean><!--property标签:设置注入属性--><!--name属性:设置注入的属性名,实际是set方法对应的名称--><!--ref属性:设置注入引用类型bean的id或name--><property name="bookDao" ref="bookDao"/><property name="userDao" ref="userDao"/></bean></beans>

构造器注入简单类型(了解)

在bean中定义简单类型属性并提供可访问的set方法

public class BookDaoImpl implements BookDao{private int connectionNumber;pubilc void setConnectionNumber(int connectionNumber){this.connectionNumber = connectionNumber;}}

配置中使用constructor-arg标签value属性注入简单类型数据

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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>根据构造方法参数名称注入<constructor-arg name="connectionNum" value="10"/></bean><bean/></beans>

构造器注入引用类型(了解)

在bean中定义引用类型属性并提供可访问的构造方法

public class BookDaoImpl implements BookDao{private BookBao bookBao;pubilc void setConnectionNumber(int connectionNumber){this.bookBao = bookBao;}}

配置中使用constructor-arg标签ref属性注入简单类型数据

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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><constructor-arg name="userDao" ref="userDao"/><constructor-arg name="bookDao" ref="bookDao"/></bean></beans>

构造器注入参数配置问题(了解)

在前面我们已经介绍了构造器的注入方法

但如果我们在bean中的数据名称发生改变,配置就不再适配,所以提供了一些方法来解决参数配置问题:

  • 配置中使用constructor-arg标签type属性设置按形参类型注入

<!--解决形参名称的问题,与形参名不耦合--><bean>根据构造方法参数类型注入<constructor-arg type="int" value="10"/><constructor-arg type="java.lang.String" value="mysql"/></bean><bean/><bean><constructor-arg name="userDao" ref="userDao"/><constructor-arg name="bookDao" ref="bookDao"/></bean>

  • 配置中使用constructor-arg标签index属性设置按形参类型注入

<!--解决参数类型重复问题,使用位置解决参数匹配--><bean><!--根据构造方法参数位置注入--><constructor-arg index="0" value="mysql"/><constructor-arg index="1" value="100"/></bean><bean/><bean><constructor-arg name="userDao" ref="userDao"/><constructor-arg name="bookDao" ref="bookDao"/></bean>

依赖注入方式选择

依赖注入方式有以下选择标准:

  1. 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
  2. 可选依赖使用setter注入进行,灵活性高
  3. Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
  4. 如果有必要可以两者并用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
  5. 实际开发中根据情况分析,如果受控对象没有提供setter方法则只能采用构造器注入
  6. 自己开发的模块尽量推荐setter注入
依赖自动装配

在前面我们学习了手动注入的方法,但Spring其实为我们提供了一种依赖自动装配的语法:

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入bean中的过程称为自动装配

自动装配方式:

  • 按类型(常用)
  • 按名称
  • 按构造方法
  • 不启用

自动装配语法:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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 /><!--autowire属性:开启自动装配,通常使用按类型装配--><beanautowire="byType"/></beans>

依赖自动装配特征:

自动装配用于引用类型注入,不能对简单类型进行操作使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用自动装配优先级低于setter注入和构造器注入,同时出现时,自动装配配置失效

依赖集合注入

除了基本类型和引入类型外,我们有时也需要注入集合

下面我们简单介绍一下结合的注入:

// 数据类 package com.itheima.dao.impl;import com.itheima.dao.BookDao;import java.util.*;public class BookDaoImpl implements BookDao {private int[] array;private List<String> list;private Set<String> set;private Map<String,String> map;private Properties properties;public void setArray(int[] array) {this.array = array;}public void setList(List<String> list) {this.list = list;}public void setSet(Set<String> set) {this.set = set;}public void setMap(Map<String, String> map) {this.map = map;}public void setProperties(Properties properties) {this.properties = properties;}public void save() {System.out.println("book dao save ...");System.out.println("遍历数组:"Arrays.toString(array));System.out.println("遍历List"list);System.out.println("遍历Set"set);System.out.println("遍历Map"map);System.out.println("遍历Properties"properties);}}

<!--xml注入--><?xml version="1.0" encoding="UTF-8"?><beans xmlns="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><!--数组注入--><!--注意:name:对应实现类中的内部成员名称<>里的array等为固定词汇--><property name="array"><array><value>100</value><value>200</value><value>300</value></array></property><!--list集合注入--><property name="list"><list><value>itcast</value><value>itheima</value><value>boxuegu</value><value>chuanzhihui</value></list></property><!--set集合注入--><property name="set"><set><value>itcast</value><value>itheima</value><value>boxuegu</value><value>boxuegu</value></set></property><!--map集合注入--><property name="map"><map><entry key="country" value="china"/><entry key="province" value="henan"/><entry key="city" value="kaifeng"/></map></property><!--Properties注入--><property name="properties"><props><prop key="country">china</prop><prop key="province">henan</prop><prop key="city">kaifeng</prop></props></property></bean></beans>

案例:数据源对象管理

针对一个新的数据源对象,我们采用两步来创建bean(我们以druid为案例):

  • 导入druid坐标

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima</groupId><artifactId>spring_09_datasource</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency><!--这里导入druid坐标--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency></dependencies></project>

  • 配置数据源对象作为Spring管理的bean

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--管理DruidDataSource对象--><!--起id 设置class地址--><bean><!--配置基本信息--><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/spring_db"/><property name="username" value="root"/><property name="password" value="123456"/></bean></beans>

案例:加载properties文件

这个案例我们将会介绍如何加载properties文件,并将文件带入到property基本信息中

我们大致将步骤分为以下三步:

  • 开辟context命名空间:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--上述beans中的内容是我们的命名空间开辟过程在原本的xml中只有:xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">在下面的内容中我们添加:xmlns:context="http://www.springframework.org/schema/context"并在xsi:schemaLocation中添加:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd(整体从上述内容复制,然后修改末尾xsi即可)--></beans>

  • 使用context命名空间,加载指定properties文件

<!--2.使用context空间加载properties文件--><context:property-placeholder location="jdbc.properties"/>

  • 使用${}读取加载的属性值

<!--3.使用属性占位符${}读取properties文件中的属性--><!--说明:idea自动识别${}加载的属性值,需要手工点击才可以查阅原始书写格式--><bean ><property name="driverClassName" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></bean>

除了上述的基本操作,我们在context命名空间的使用中有很多需要注意的点:

  • 不加载系统属性

<!--因为我们的系统属性优先级>定义优先级,当我们properties中的属性与系统设置属性名相同时,会优先匹配系统属性导致错误可以采用system-properties-mode进行设置--><context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>

  • 加载多个properties文件

<!--我们可以采用逗号或空格分隔加载多个properties文件--><context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>

  • 加载所有properties文件

<!--我们可以采用通配符来设置加载文件用*来代替所有前缀,只保留后缀为properties即可--><context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>

  • 加载properties文件标准格式

<!--我们通常以classpath表示路径,下述形式更为标准classpath:*.properties:设置加载当前工程类路径中的所有properties文件--> <context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>

  • 从类路径或jar包中搜索并加载properties文件

<!--我们通常以classpath*来表示路径来源classpath*:*.properties:设置加载当前工程类路径和当前工程所依赖的所有jar包中的所有properties文件--><context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>

核心容器

前面已经完成bean与依赖注入的相关知识学习,接下来我们主要学习的是IOC容器中的核心容器。

这里所说的核心容器,大家可以把它简单的理解为ApplicationContext,接下来我们从以下几个问题入手来学习下容器的相关知识:

  • 如何创建容器?
  • 创建好容器后,如何从容器中获取bean对象?
  • 容器类的层次结构是什么?
  • BeanFactory是什么?
容器的创建方式

案例中创建ApplicationContext的方式为(类路径下的XML配置文件):

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

除了上面这种方式,Spring还提供了另外一种创建方式为(文件的绝对路径):

ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\workspace\\spring\\spring_10_container\\src\\main\\resources\\applicationContext.xml");

Bean的三种获取方式

方式一,就是目前案例中获取的方式:

BookDao bookDao = (BookDao) ctx.getBean("bookDao");

这种方式存在的问题是每次获取的时候都需要进行类型转换

方式二:

BookDao bookDao = ctx.getBean("bookDao",BookDao.class);

这种方式可以解决类型强转问题,但是参数又多加了一个,相对来说没有简化多少。

方式三:

BookDao bookDao = ctx.getBean(BookDao.class);

这种方式就类似我们之前所学习依赖注入中的按类型注入。必须要确保IOC容器中该类型对应的bean对象只能有一个。

容器类层次结构

下面我们给出容器的层次图

BeanFactory的使用

使用BeanFactory来创建IOC容器的具体实现方式为:

public class AppForBeanFactory {public static void main(String[] args) {Resource resources = new ClassPathResource("applicationContext.xml");BeanFactory bf = new XmlBeanFactory(resources);BookDao bookDao = bf.getBean(BookDao.class);bookDao.save();}}

为了更好的看出BeanFactory和ApplicationContext之间的区别,在BookDaoImpl添加如下构造函数:

public class BookDaoImpl implements BookDao {public BookDaoImpl() {System.out.println("constructor");}public void save() {System.out.println("book dao save ..." );}}

如果不去获取bean对象,打印会发现:

  • BeanFactory是延迟加载,只有在获取bean对象的时候才会去创建
  • ApplicationContext是立即加载,容器加载的时候就会创建bean对象
  • ApplicationContext要想成为延迟加载,只需要按照如下方式进行配置
  • <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="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"> <beanlazy-init="true"/> </beans>
核心概念总结

接下来我们对前面知识的一个总结,共包含如下内容:

容器相关
  • BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
  • ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
  • ApplicationContext接口常用初始化类ClassPathXmlApplicationContext(常用)FileSystemXmlApplicationContext
bean相关依赖注入相关注解开发

在上述的开发中,我们采用xml配置文件的形式来说依旧显得有些复杂

这时我们就需要发挥Spring的优点:简化开发,通过注解来简化开发过程

下面我们会通过多个方面将Bean逐步转化为注解

注解开发Bean

在前面的内容中,我们的bean在xml配置文件中装配

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="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--><bean/></beans>

在后期,我们的bean可以采用注解的形式,直接在实现类中注解表示为bean

我们采用@Component定义bean,可以添加参数表示id,也可以不添加参数,后期我们采用class类的类型来进行匹配

package com.itheima.dao.impl;import com.itheima.dao.BookDao;import org.springframework.stereotype.Component;import org.springframework.stereotype.Controller;import org.springframework.stereotype.Repository;//@Component定义bean@Component("bookDao")public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}

package com.itheima.service.impl;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;//@Component定义bean@Componentpublic class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}}

@Componenty延伸出了三种类型,在实现手法上是一致,但可以具体使用于各种类中(仅用于自我识别)

  • @Controller:用于表现层bean定义
  • @Service:用于业务层bean定义
  • @Repository:用于数据层定义

package com.itheima.dao.impl;import com.itheima.dao.BookDao;import org.springframework.stereotype.Component;import org.springframework.stereotype.Controller;import org.springframework.stereotype.Repository;//@Component定义bean//@Component("bookDao")//@Repository:@Component衍生注解@Repository("bookDao")public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}

package com.itheima.service.impl;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.stereotype.Component;import org.springframework.stereotype.Service;//@Component定义bean//@Component//@Service:@Component衍生注解@Servicepublic class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}}

但是,在上述情况下,即使我们将@Component的类定义为bean

我们的xml文件是无法探测到的,所以我们需要配置相关扫描组件来扫描bean

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--<context:component-scan />:表示扫描文件base-package:表示扫描路径--><context:component-scan base-package="com.itheima"/></beans>

纯注解开发

我们前面所提到的注解开发属于2.5的附属版本

在Spring3.0版本,Spring就提供了纯注解开发模式,利用java类代替配置文件,开启了Spring快速开发时代

在之前我们的xml配置文件是很繁琐的:

<!--原生xml配置文件--><?xml version="1.0" encoding="UTF-8"?><beans xmlns="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/></beans>

但是我们可以通过创建单独的类来表示配置文件:

  • @Configuration:用于声明当前类为Spring配置类
  • @ComponentScan:用于扫描类文件(类似于<context:component-scan base-package="com.itheima"/>)

package com.itheima.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;//声明当前类为Spring配置类@Configuration//设置bean扫描路径,多个路径书写为字符串数组格式@ComponentScan({"com.itheima.service","com.itheima.dao"})public class SpringConfig {}

注意:因为该类属于配置类,我们通常单列一个文件夹来表示

常用文件夹:config

命名规范:SpringConfig,UserConfig...

因为我们的开发不再依靠于xml配置文件,所以在主函数中的Spring容器获得方式也发生了改变:

package com.itheima;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {// 这是我们之前的获取方式,采用路径获取xml文件// ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");// 这是新的获取方式,直接提供配置类的类型// AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);// 后面操作无需变化BookDao bookDao = (BookDao) ctx.getBean("bookDao");System.out.println(bookDao);//按类型获取beanBookService bookService = ctx.getBean(BookService.class);System.out.println(bookService);}}

注解开发Bean作用范围与管理

既然我们的Bean开发从xml转移到注解开发,那么一些配置设置同样发生改变

首先我们介绍Scope范围的设置方式:

  • @Scope:定义bean的作用范围

package com.itheima.dao.impl;import com.itheima.dao.BookDao;import org.springframework.context.annotation.Scope;import org.springframework.stereotype.Repository;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;@Repository//@Scope设置bean的作用范围(singleton或prototype),可以不添加默认singleton@Scope("singleton")public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}

然后我们介绍一下bean生命周期的init和destroy操作:

  • @PostConstruct:定义init操作,表示构造后操作
  • @PreDestroy:定义destroy操作,表示销毁前操作
依赖注入(自动装配)

在Spring3.0中,省略掉了前面繁琐的依赖注入,我们的bean依赖注入只留下了自动装配这一操作:

  • 使用@Autowired注解开启自动装配模式(按类型)
  • 当存在相同类型时,我们采用@Qualifier开启按名自动装配

package com.itheima.service.impl;import com.itheima.dao.BookDao;import com.itheima.service.BookService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;@Servicepublic class BookServiceImpl implements BookService {//@Autowired:注入引用类型,自动装配模式,默认按类型装配@Autowired//@Qualifier:自动装配bean时按bean名称装配@Qualifier("bookDao")private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}}

注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法

注意:自动转配建议使用无参构造方法创建对象(默认),如果不提供对应构造方法,请提供唯一的构造方法

注意:@Qualifier是基于@Autowired实现的,必须保证先有Autowired才能存在Qualifier

除了上述的bean类型装配,我们的简单类型装配依旧存在:

  • 我们采用@Value的形式来配置简单类型的值

package com.itheima.dao.impl;import com.itheima.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Repository;@Repository("bookDao")public class BookDaoImpl implements BookDao {//@Value:注入简单类型(无需提供set方法)@Value("123")private String name;public void save() {System.out.println("book dao save ..."name);}}

之所以使用@Value的形式配置,是因为我们的类型值不一定是由手动输入的,有可能来自于Properties资源:

  • 首先我们需要在Springconfig中配置相关资源

package com.itheima.config;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;@Configuration@ComponentScan("com.itheima")//@PropertySource加载properties配置文件@PropertySource({"jdbc.properties"})public class SpringConfig {}

  • 然后我们在数据层调用时,采用${}来匹配数据

package com.itheima.dao.impl;import com.itheima.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Repository;@Repository("bookDao")public class BookDaoImpl implements BookDao {//@Value:注入简单类型(无需提供set方法)@Value("${name}")private String name;public void save() {System.out.println("book dao save ..."name);}}

注解开发第三方bean

我们在实际开发中不仅仅需要对自己的bean进行管理,有时候可能需要引进其他的bean

下面我们以Druid为例进行讲解:

  1. 首先在pom.xml中导入Druid坐标

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.itheima</groupId><artifactId>spring_14_annotation_third_bean_manager</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency></dependencies></project>

  1. 使用@Bean配置第三方Bean

// 该bean同样属于config文件,我们同样放置在config文件夹下// 在后续我们将会讲解如何进行连接package com.itheima.config;import com.alibaba.druid.pool.DruidDataSource;import com.itheima.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;public class JdbcConfig {// 1.定义一个方法获得要管理的对象// 2.添加@Bean,表示当前方法的返回值是一个bean// @Bean修饰的方法,形参根据类型自动装配@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/spring_db");ds.setUsername("root");ds.setPassword("123456");return ds;}}

  1. 将独立的配置类加入核心配置(导入法)

// SpringConfigpackage com.itheima.config;import com.alibaba.druid.pool.DruidDataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import javax.sql.DataSource;@Configuration@ComponentScan("com.itheima")//@Import:导入配置信息(如果需要多个,同样采用{}数组形式)@Import({JdbcConfig.class})public class SpringConfig {}

// JdbcConfigpackage com.itheima.config;import com.alibaba.druid.pool.DruidDataSource;import com.itheima.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;//@Configurationpublic class JdbcConfig {//@Bean修饰的方法,形参根据类型自动装配@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();// 配置信息return ds;}}

注意:除了上述的导入法外还存在有其他方法,但导入法属于主流,因此我们不介绍其他流派,感兴趣的同学可以去查阅一下

注解开发为第三方导入资源

我们的第三方bean也可能需要导入部分资源,下面我们进行简单介绍:

  • 简单类型依赖注入

package com.itheima.config;import com.alibaba.druid.pool.DruidDataSource;import com.itheima.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;//@Configurationpublic class JdbcConfig {//1.定义一个方法获得要管理的对象@Value("com.mysql.jdbc.Driver")private String driver;@Value("jdbc:mysql://localhost:3306/spring_db")private String url;@Value("root")private String userName;@Value("root")private String password;//2.添加@Bean,表示当前方法的返回值是一个bean//@Bean修饰的方法,形参根据类型自动装配@Beanpublic DataSource dataSource(){DruidDataSource ds = new DruidDataSource();ds.setDriverClassName(driver);ds.setUrl(url);ds.setUsername(userName);ds.setPassword(password);return ds;}}

  • 依赖类型依赖注入

package com.itheima.config;import com.alibaba.druid.pool.DruidDataSource;import com.itheima.dao.BookDao;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;public class JdbcConfig {@Beanpublic DataSource dataSource(BookDao bookDao){// 我们只需要调用即可,系统会为我们自动装配System.out.println(bookDao);}}

引入类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

原文链接:https://www.cnblogs.com/qiuluoyuweiliang/p/16750470.html

,
    推荐阅读
  • 如何立足岗位发挥好示范引领作用(如何发挥好岗位的示范和引领作用)

    跟着小编一起来看一看吧!如何立足岗位发挥好示范引领作用首先要做实践的模范。要忠实履行政协会议的各种决议,自觉遵守各项工作制度,正确行使自己的民主权力。中共党员中的政协委员,不论是在政协组织的活动中,还是在日常工作生活中,都要积极地进行调查研究,了解最新动态,了解社会各方面的真实情况,了解群众的情绪、困难和诉求,充分反映他们的要求和呼声,使党委和政府能及时采纳他们对党和政府工作的意见建议。

  • 海底捞 摄像头(海底捞包间内安装摄像头遭质疑)

    对于安装摄像头是否会侵犯隐私,网友各执一词。安装了摄像头的门店也表示,安装主要是为了防止客人丢失东西,方便找回。不过,北青报记者进一步采访其安装摄像头的必要性时,截至发稿时,海底捞方面暂时没有回应。图像信息系统在营业期间应当正常运行,不得中断。在这一规定中,包间并未罗列其中。此前曾有调查称,在30家火锅店中,有19家在包间装有摄像头;在14家非火锅店中,也有2家的包间装有摄像头。

  • 讯飞智能语音服务(IQEQ齐上阵讯鸟软件打造更有)

    讯飞智能语音服务埃森哲调研显示:多达75%的高管表示,自己的组织将在未来三年积极部署某种人工智能技术,AI将作为一名同事、合作者和值得信赖的顾问,在企业中与人类并肩协作。智能客服语音机器人能够支持语音情感三分类、四分类和六分类,在各类应用场景下识别率均超过85%,在成熟的业务场景下识别准确率可高达95%。

  • 提高fps的方法csgo(FPS游戏CSGO之身位控制)

    FPS游戏CSGO之身位控制​高手与菜鸟最大的差距也许还不是枪法,而是存活率同样的一个点位,菜鸟去看点,永远是拉一个大身位,同时暴露在复数架枪点的准星内,所以死亡率奇高无比高手的身法多变,身位控制良好,知道适当切换行进节奏与路线。

  • 怎么用微信支付(用微信支付的方法介绍)

    怎么用微信支付?最简单的,看到各个超市或者别的地方的收银台都会贴有一张二维码图片,上面写着微信支付,就可以使用手机微信来支付了,打开手机微信,右上角有一个的标志,点击它,下面我们就来聊聊关于怎么用微信支付?接下来我们就一起去了解一下吧!这是把商家的二维码放到相机前,就可以自动扫描了,扫描出来后,可以看到要付款的别人的微信名称,可以核对一下,没问题就输入金额,完成付款。

  • 白萝卜多久能煮熟(白萝卜怎么煮)

    下面更多详细答案一起来看看吧!白萝卜多久能煮熟通常情况下,白萝卜水只要煮十五到二十分钟就差不多了。白萝卜煮水的做法非常简单,我们平时如果想要喝白萝卜水的话都可以自己在家里制作。制作它首先要把准备好的白萝卜清洗干净并切成片状或是块状,注意这里是不需要给萝卜去皮的。在白萝卜处理好之后,我们就可以准备一口锅并往里面倒入适量的清水加热。

  • 键盘和电脑怎么清洁(干货清洁电脑屏幕)

    键盘和电脑怎么清洁DTECH帝特,传递精彩画面,分享快乐时光!这种情况,我们可以购买专用液晶屏幕清洁剂进行清洁,价格大概在20~50元之间,通常专用清洁剂都有详细的使用说明。以上几个清洁方法都需要有规则地轻轻擦拭屏幕,不可以用力按着擦,否则容易给屏幕造成坏点。

  • 茉莉飘雪茶的功效与作用(关于茉莉飘雪茶的功效与作用)

    茉莉飘雪茶的功效与作用茉莉花茶是花茶中的典型,茉莉飘雪花茶能够帮助人体降血脂,有利于人体内脂肪的分解,还有一定的清除氧自由基作用,所以能够起到抗氧化、防衰老的功效。茉莉飘雪花茶能够起到保肝护肝、美容养颜的作用,同时还有一定杀菌、抗菌、增强机体免疫力的作用,可以预防感染性疾病,因为茉莉花茶中含有的营养物质比较丰富,能够提高机体的免疫力,也能够对抗疾病的发生。

  • 堕仙是指什么意思(堕仙出现在哪位人物身上呢)

    堕仙是指什么意思是指堕落的仙人,也指走火入魔,因为面对让自己万分痛苦的事而无法承受,后变为魔的紫薰上仙。紫薰上仙堕仙成魔是因一直守护她的檀凡上仙为救她而死,紫薰上仙觉得对不起檀凡上仙,又很愤怒于白子画的漠不关心,所以成为堕仙。求而不得,一念成魔。本是仙界的紫薰仙子,五上仙之一,擅长制香,因痴恋白子画而成为堕仙,坠入魔道。后被花千骨感动,放下执念,将所有功力传给白子画,成全白子画与花千骨。

  • 想让学习强国由青铜变成骨灰吗(想让学习强国由青铜变成骨灰吗)

    A、正确B、错误正确答案:A135、我国鼓励各类市场主体在有效保护旅游资源的前提下,依法合理利用旅游资源。A、正确B、错误正确答案:A137、2021年1月22日,我国首部战疫纪录电影上映,影片以平实的语言讲述了武汉人与来自全国各地医疗系统及其他行业的一线人员,一起打响武汉抗击新冠肺炎疫情阻击战。A、50%B、60%C、70%D、80%正确答案: