002 IOC和DI使用

文章目录

    • 基于XML的使用
      • IOC配置
      • 第三种:实例工厂(了解)
      • DI配置
        • 构造函数注入
        • set方法注入(重点)
        • 使用p名称空间注入数据
        • 依赖注入不同类型的属性
    • 基于注解和XML混合方式的使用
      • IoC注解使用方法
      • IoC注解(创建对象)
      • DI注解(依赖注入)
      • 关于注解和XML的选择问题
    • 基于纯注解方式使用
      • 注解和XML混合开发遗留的问题

基于XML的使用

IOC配置

在Spring的XML文件中通过一个bean标签,完成IoC的配置
bean标签介绍

  • bean标签作用:
    用于配置被spring容器管理的bean的信息
    默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功
  • bean标签属性:
    id:给对象在容器中提供一个唯一标识,用于获取对象
    class:指定类的全限定名,用于反射创建对象,默认情况下调用无参构造函数
    init-method:指定类中的初始化方法名称
    destory-method:指定类中的销毁方法名称。比如DataSource的配置中一般需要指定destory-method = “close”
    scope:指定对象的作用范围
    singleton:默认值,单例的(在整个容器中只有一个对象),生命周期如下:
    对象出生:当应用加载,创建容器时,对象就被创建了
    对象活着:只要容器在,对象一直活着
    对象死亡:当应用卸载,销毁容器时,对象就被销毁了
    prototype:多例的,每次访问对象时,都会重新创建对象实例,生命周期如下:
    对象出生:当使用对象时,创建新的对象实例
    对象活着:只要对象在使用中,就一直活着
    对象死亡:当对象长时间不用时,被java的垃圾回收器回收
    request:将Spring创建的Bean对象存入到request域中
    session:将Spring创建的Bean对象存入到session域中
    global session:WEB项目中,应用在Portlet环境。如果没有Portlet环境,那么global session相当于session

bean实例化的三种方式
第一种:使用默认无参构造函数
在默认情况下:它会根据默认无参构造函数来创建对象
如果bean中没有默认无参构造函数,将会创建失败

<bean id="userService" class="com.UserServiceImpl"/>

第二种:静态工厂(了解)
使用StaticFactory类中的静态方法 createUserService创建对象,并存入spring容器

/**
* 模拟一个静态工厂,创建业务层实现类
*/
public class StaticFactory {public static UserService createUserService{return new UserServiceImpl();}}
<bean id="userService" class="com.StaticFactory" factory-method="createUserService"></bean>
<!-- 此种方式是:
使用StaticFactory类中的静态方法createUserService创建对象,并存入spring容器
id属性:指定bean的id,用于从容器中获取
class属性:指定静态工厂的全限定类名
factory-method:指定生产对象的的静态方法
-->

第三种:实例工厂(了解)

/**
*	模拟一个实例工厂,创建业务层实现类
*	此工厂创建对象,必须现有工厂实例对象,再调用方法
*/
public class InstanceFactory {public UserService createUserService(){return new UserServiceImpl();}
}
<bean id="instancFactory" class="com.InstanceFactory"></bean><bean id="userService" factory-bean="instancFactory" factory-method="createUserService"></bean>
<!-- 此种方式是
先把工厂的创建交给spring来管理
然后再使用工厂的bean来调用里面的方法
factory-bean属性:用于指定实例工厂bean的id
factory-method属性:用于指定实例工厂中创建对象的方法-->

DI配置

概述

  • 什么是依赖

依赖指的就是Bean实例中的属性
依赖(属性)分为:简单类型(8种基本类型和String类型)的属性、POJO类型的属性、集合数组类型的属性

  • 什么是依赖注入

依赖注入:Dependency Injection,它是spring框架核心IoC的具体实现

  • 为什么要进行依赖注入

我们的程序在编写时,通过控制反转,把对象的创建交给了spring,但是代码中不可能出现没有依赖的情况
那如果一个bean中包含了一些属性,那么spring帮我们实例化了bean对象后,也需要将对应的属性信息进行赋值操作,这种属性赋值操作,就是所谓的依赖注入(获取值,注入属性)

依赖注入的方式

构造函数注入

顾名思义,就是使用类中的构造函数,给成员变量赋值。注意:赋值的操作不是我们自己做的,而是通过配置的方式,让spring框架来为我们注入

public class UserServiceImpl implements UserService {private int id;private String name;public UserServiceImpl(int id, String name) {this.id = id;this.name = name;}@Overridepublic void saveUser(){System.out.println("保存用户:id为"+id+",name为"+name+"  Service实现")}}
<bean id="userService" class="com.UserServiceImpl"><constructor-arg name="id" value="1"></constructor-arg><constructor-arg name="name" value="zhangsan"></constructor-arg>
</bean>
<!--使用构造函数的方式,给service中的属性传输要求:类中需要提供一个对应参数列表的构造函数
涉及的标签:constructor-arg
index:指定参数在构造函数参数列表的索引位置
name:指定参数在构造函数中的名称
value:它能赋的值是基本数据类型和String类型
ref:它能赋的值是其他bean类型,也就是说,必须是得在配置文件中配置的bean-->
set方法注入(重点)
  • 手动装配方式(XML方式)

需要配置bean标签的子标签property
需要配置bean中指定setter方法

  • 自动装配方式(注解方式)

@Autowired:
作用一:查找实例,从spring容器中根据Bean的类型(byType)获取实例
作用二:赋值,将找到的实例,装配给另一个实例的属性值
注意事项:一个java类型在同一个spring容器中,只能有一个实例
@Resource:
作用一:查找实例,从spring容器中根据Bean的名称(byName)获取实例
作用二:赋值,将找到的实例,装配给另一个实例的属性值
@Inject

使用p名称空间注入数据

本质上还是调用set方法
1.步骤一:需要先引入p名称空间

在schema的名称空间中加入该行:xmlns:p="http://www.springframework.org/schema/p"

2.步骤二: 使用p名称空间的语法

p:属性名 = ""
p:属性名-ref = ""

3.步骤三:测试

<bean id="person" class="com.Person" p:pname="老王" p:car2-ref="car2"/>
<bean id="car2" class="com.Car2"></bean>
依赖注入不同类型的属性

简单类型(value)

<bean id="userService" class="com.UserServiceImpl"><property name="id" value="1"></property><property name="name" value="zhangsan"></property>
</bean>

引用类型(ref)
ref就是reference的缩写,是引用的意思

<bean id="userService" class="com.UserServiceImpl"><property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="com.UserDaoImpl"></bean>

集合类型(数组)
1.如果是数组或List集合,注入配置文件的方式是一样的

<bean id="collectionBean" class="com.CollectionBean"><property name="arrs"><list><!--如果集合内是简单类型,使用value子标签,如果是POJO类型,则使用bean标签--><value>aa</value><value>bb</value><bean></bean></list></property>
</bean>

2.如果是Set集合,注入的配置文件方式如下

<property name="sets"><set><!--如果集合内是简单类型,使用value子标签,如果是POJO类型,则使用bean标签--></set>
</property>

3.如果是Map集合,注入的配置方式如下

<property name="map"><map><entry key="老王" value="38"><entry key="张三" value="38"></map>
</property>

4.如果是Properties集合的方式,注入的配置如下

<property name="pro"><props><prop key="name">root</prop><prop key="pass">123456</prop></props>
</property>

基于注解和XML混合方式的使用

IoC注解使用方法

  • 第一步:spring配置文件中,配置context:compent-scan标签
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 开启注解并扫描指定包中带有注解的类 --><context:component-scan base-package="com.service"></context:component-scan>
  • 第二步:类上面加上注解@Component,或者它的衍生注解@Controller、@Service、@Repository
@Service
public class UserServiceImpl implements UserService {
}

IoC注解(创建对象)

相当于:

<bean id="" class="">

Component注解

  • 作用:

把资源让spring管理。相当于在xml中配置一个bean

  • 属性

value:指定bean的id。如果不指定value属性,默认bean的id是当前类的类名,首字母小写

Controller&Service&Repository注解
他们三个注解都是针对@Component的衍生注解,他们的作用及属性都是一模一样的。他们只不过是提供了更加明确的语义化。
注意:如果注解中有且只有一个属性要赋值时,且名称是value,value在赋值时可以不写。

@Controller:一般用于表现层的注解
@Service:一般用于业务层的注解
@Repository:一般用于持久层的注解

DI注解(依赖注入)

相当于:

<property name="" ref="">
<property name="" value="">

@Autowired

  • @Autowired默认按类型装配(byType)
  • @Autowired是由AutowiredAnnotationBeanPostProcessor类实现
  • @Autowired是spring自带的注解
  • @Autowired默认情况下要求依赖对象必须存在,如果需要允许null值,可以设置它的required属性为false,如:@Autowired(required=false)
  • 如果我们想按名称装配(byName)可以结合@Qualifier注解进行使用

@Qualifier

  • 在自动按照类型注入的基础之上,再按照Bean的id注入
  • 它在给字段注入时不能独立使用,必须和@Autowired一起使用
  • 但是给方法参数注入时,可以独立使用

@Resource

  • @Resource默认按名称装配(byName),可以通过@Resource的name属性指定名称,如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,当找不到与名称匹配的bean时才按照类型进行装配。
  • @Resource属于J2EE JSR250规范的实现
  • 但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配
    推荐使用@Resource注解,因为它是属于J2EE的,减少了与spring的耦合。这样代码看起来比较优雅

@Inject

  • @Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named
  • @Inject是JSR330中的规范,需要导入javax.inject.Inject实现注入
  • @Inject可以作用在变量、setter方法、构造函数上

@Value

  • 给基本类型和String类型注入值
  • 可以使用占位符获取属性文件中的值
@Value("${name}")//name是properties文件中的key
private String name;

@Autowired、@Resource、@Inject区别
1.@Autowired是spring自带的,@Inject是JSR330规范实现的,@Resource是JSR250规范实现的,需要导入不同的包
2.@Autowired、@Inject用法基本一样,不同的是@Autowired有一个request属性
3.@Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的
4.@Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用

改变bean作用范围的注解

  • @Scope:指定bean的作用范围,相当于下面的配置
<bean id="" class="" scope="">
  • 属性

value:指定范围的值。 取值:singleton prototype request session globalsession

生命周期相关注解

  • @PostConstruct
  • @PreDestory
    相当于
<bean id="" class="" init-method="" destory-method="" />

关于注解和XML的选择问题

  • 注解的优势
    配置简单,维护方便(找到了类,就相当于找到了对应的配置)
  • XML的优势
    修改时,不用改源码。不涉及重新编译和部署
  • Spring管理Bean方式的比较
基于XML配置基于注解配置
Bean定义<bean id=“…” class=“…” />@Component衍生类@Repository @Service @Controller
Bean名称通过id或name指定@Component(“person”)
Bean注入<property>或者通过p命名空间@Autowired按类型注入 @Qualifier按名称注入
生命过程、Bean作用范围init-method destory-method范围scope属性@PostConstruct初始化 @PreDestory销毁 @Scope设置作用范围
适合场景Bean来自第三方,使用其他Bean的实现类由用户自己开发

基于纯注解方式使用

注解和XML混合开发遗留的问题

想想能不能将以下这些bean的配置都从xml中去掉,并且最终将XML也去掉。如果可以,就可以脱离xml配置

  • 注解扫描配置
<!-- 开启注解并扫描指定包中带有注解的类-->
<context:component-scan base-package="com.service"/>
<context:property-placeholder src=""></context:property-placeholder>
  • 非自定义的Bean配置(比如:SqlSessionFactory和BasicDataSource配置)
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" value="dataSource"></property>
</bean>
  • 去掉XML后,如何创建ApplicationContext
    之前创建ApplicationContext都是通过读取XML文件进行创建的

ApplicationContext context = new ClassPathXmlApplicationContext(“beans.xml”);

@Configuration

相当于spring的XML配置文件
从Spring3.0开始可以使用@Configuration定义配置类,可替换xml配置文件
配置类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义对象,初始化Spring容器

  • 属性
    value:用于指定配置类的字节码
  • 示例代码
@Configuration
public class SpringConfiguration {//spring容器初始化时,会调用配置类的无参构造函数public SpringConfiguration(){System.out.println("容器启动初始化。。。");}
}

@Bean

相当于<bean>标签
作用为:注册bean对象,主要用来配置非自定义的bean,比如DruidDataSource、SqlSessionFactory
@Bean标注在方法上(返回某个实例的方法)

  • 属性

name:给当前@Bean 注解方法创建的对象指定一个名称(即bean的id)。如果不指定,默认与标注的方法名相同
@Bean注解默认作用域为单例singleton作用域,可通过@Scope(“prototype”)设置为原型作用域

  • 示例代码
@Configuration
public class SpringConfiguration {//spring容器初始化时,会调用配置类的无参构造函数public SpringConfiguration(){System.out.println("容器启动初始化。。。");}@Bean@Scope("prototype")public SqlSessionFactory userService(){SqlSessionFactory sqlSessionFactory = new DefaultSqlSessionFactory();sqlSessionFactory.setxxx();return sqlSessionFactory;}}

@ComponentScan

相当于context:component-scan标签
组件扫描器,扫描@Component、@Controller、@Service、@Repository注解的类
该注解是编写在类上面的,一般配合@Configuration注解一起使用

  • 属性

basePackages:用于指定要扫描的包
value:和basePackages作用一样

  • 示例代码
    Bean类(Service类):
@Service
public class UserServiceImpl implements UserService {@Overridepublic void saveUser() {System.out.println("保存用户 Service实现");}
}

配置类:

@Configuration
@ComponentScan(basePackages="com.service")
public class SpringConfiguration {public SpringConfiguration() {System.out.println("容器初始化...");}// @Bean// @Scope("prototype")// public UserService userService() {// 	return new UserServiceImpl(1,"张三");//}
}

@PropertySource

相当于context:property-placeholder标签
编写在类上面,作用是加载properties配置文件

  • 属性

value[]:用于指定properties文件路径,如果在类路径下,需要写上classpath

  • 示例代码
    配置类:
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {@Value("${jdbc.driver}")private String driver;@Value("${jdbc.url}")private String url;@Value("${jdbc.username}")private String username;@Value("${jdbc.password}")private String password;/*** 创建一个数据源,并存入spring容器中* @return*/@Bean(name = "dataSource")public DataSource createDataSource() {try {ComboPooledDataSource ds = new ComboPooledDataSource();ds.setDriverClass(driver);ds.setJdbcUrl(url);ds.setUser(username);ds.setPassword(password);return ds;} catch (Exception e) {throw new RuntimeException(e);}}}

properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring
jdbc.username=root
jdbc.password=root

  • 问题

当系统中有多个配置类时怎么办?想一想之前使用XML配置的时候是如何解决该问题的

@Import

相当于spring配置文件中的<import>标签
用来组合多个配置类,在引入其他配置类时,可以不用再写@Configuration注解。当然,写上也没问题

  • 属性

value:用来指定其他配置类的字节码文件

  • 示例代码
@Configuration
@ComponentScan(basePackages = "com.spring")
@Import({JdbcConfig.class})
public class SpringConfiguration {
}@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
}

创建纯注解方式上下文容器

  • Java应用(AnnotationConfigApplicationContext)
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfiguration.class);
UserService service = context.getBean(UserService.class);
service.saveUser();
  • Web应用(AnnotationConfigWebApplicationContext)
<web-app><context-param><param-name>contextClass</param-name><param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value></context-param><context-param><param-name>contextConfigLocation</param-name><param-value>com.SpringConfiguration</param-value></context-param><listener><listener-class>org.springframe.web.context.ContextLoaderListener</listener-class></listener>
</web-app>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【字符串函数】

1.strlen的使⽤和模拟实现 size_t strlen ( const char * str ); 1.字符串以 \0 作为结束标志&#xff0c;strlen函数返回的是在字符串中 \0 前⾯出现的字符个数&#xff08;不包 含 \0 )。 2.参数指向的字符串必须要以 \0 结束。 3.注意函数的返回值为size_t&#xff0c;是⽆…

代码随想录算法训练营刷题复习3:动态规划——子序列问题

子序列问题 包含四个子问题&#xff1a;子序列&#xff08;不连续&#xff09;、子序列&#xff08;连续&#xff09;、编辑距离、回文 子序列&#xff08;不连续&#xff09; 300.最长递增子序列 定义dp数组&#xff0c;问什么dp的定义就设什么&#xff0c; 更新dp[i]的值&…

力扣148. 排序链表

给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4] 示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5] 示例 3&…

23 华三(自动获取的IP地址)

华三交换机 DHCP 配置 #version 7.1.070, Alpha 7170 //设备的版本信息 #sysname sw1 //修改设备的名字 #irf mac-address persistent timerirf auto-update enableundo irf link-delayirf member 1 priority 1#dhcp enable //开启DHCP 服务dhcp server forbidden-ip 192.168.…

.net 调用海康SDK的常用操作封装

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;我们面对的不仅…

2024/6/16周报

文章目录 摘要Abstract文献阅读题目问题本文贡献方法aGNN输入和输出模块嵌入模块编码器和解码器模块&#xff1a;支持多头注意的GCN多头自注意力机制GCN模型解释&#xff1a;SHAP 案例研究地下水流动与污染物运移模型研究场景设计 数据集实验结果 代码复现结论 摘要 本周阅读了…

whisper 模型源码解读

whisper官方源码 whisper 模型官方代码&#xff1a;https://github.com/openai/whisper/blob/main/whisper/model.py &#xff1b;注释如下 import base64 import gzip from dataclasses import dataclass from typing import Dict, Iterable, Optionalimport numpy as np impo…

java设计模式和面向对象编程思想

Java设计模式和面向对象编程思想是软件开发中的核心概念&#xff0c;对于构建可维护、可扩展的软件系统至关重要。下面是对这两个主题的知识点总结&#xff1a; 面向对象编程&#xff08;OOP&#xff09;思想 封装&#xff1a;将数据&#xff08;属性&#xff09;和操作这些数据…

享元和代理模式

文章目录 享元模式1.引出享元模式1.展示网站项目需求2.传统方案解决3.问题分析 2.享元模式1.基本介绍2.原理类图3.外部状态和内部状态4.类图5.代码实现1.AbsWebSite.java 抽象的网站2.ConcreteWebSite.java 具体的网站&#xff0c;type属性是内部状态3.WebSiteFactory.java 网站…

CSS从入门到精通——动画:CSS3动画执行次数和逆向播放

目录 任务描述 相关知识 动画执行次数 动画反向播放 编程要求 任务描述 本关任务&#xff1a;用 CSS3 实现loading效果。效果图如下&#xff1a; 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.动画执行次数&#xff0c;2.动画反向播放。 需要实现的效…

Go 的 netpoll 如何避免洪泛攻击

Go 的 netpoll&#xff08;网络轮询器&#xff09;组件在其网络库中扮演了一个关键角色&#xff0c;它用来高效地处理大量的网络事件&#xff0c;特别是在高并发环境下。 然而&#xff0c;防止洪泛攻击&#xff08;如 SYN Flood、UDP Flood&#xff09;并不仅仅是 netpoll 本身…

持续总结中!2024年面试必问 20 道并发编程面试题(九)

上一篇地址&#xff1a;持续总结中&#xff01;2024年面试必问 20 道并发编程面试题&#xff08;八&#xff09;-CSDN博客 十七、请解释什么是Callable和FutureTask。 Callable和FutureTask是Java并发API中的重要组成部分&#xff0c;它们用于处理可能产生结果的异步任务。 …

Oracle中select取值后的字符串处理

取一对括号中间内容 SELECT SUBSTR(column_name, INSTR(column_name, () 1, INSTR(column_name, )) - INSTR(column_name, () - 1) AS content_between_parentheses FROM table_name; 某字符值中abc之后def之前部分 SELECTSUBSTR(your_column, INSTR(your_column, abc) LEN…

R调用Taxonkit展示系统发育信息

Introduction TaxonKit是一个用于处理生物分类学数据的命令行工具。 它的主要功能是处理NCBI的生物分类学数据&#xff0c;包括对分类单元&#xff08;如物种、属、科等&#xff09;的查找、分类单元的上下位关系查询、分类单元名称的标准化等。 为了方便R社区用户&#xff0…

Spring-web-HttpServletRequest

在spring mvc中&#xff0c;有2种方法获取当前http请求的request&#xff0c;分别如下 方式1&#xff1a; spring mvc将当前request从抽象类FrameworkServlet的processRequest方法中放进去&#xff0c;然后我们通过下面代码拿出来 HttpServletRequest request ((ServletRequ…

【计算机组成原理】指令系统考研真题详解之拓展操作码!

计算机组成原理&#xff1a;指令系统概述与深入解析 1. 指令系统概述 计算机软硬件界面的概念 在计算机组成原理中&#xff0c;指令系统扮演着至关重要的角色&#xff0c;它是计算机软硬件界面的核心。软件通过指令与硬件进行通信&#xff0c;硬件根据指令执行相应的操作。指…

装饰者模式(设计模式)

装饰模式就是对一个类进行装饰&#xff0c;增强其方法行为&#xff0c;在装饰模式中&#xff0c;作为原来的这个类使用者还不应该感受到装饰前与装饰后有什么不同&#xff0c;否则就破坏了原有类的结构了&#xff0c;所以装饰器模式要做到对被装饰类的使用者透明&#xff0c;这…

如何解决javadoc一直找不到路径的问题?

目录 一、什么是javadoc二、javadoc为什么会找不到路径三、如何解决javadoc一直找不到路径的问题 一、什么是javadoc Javadoc是一种用于生成Java源代码文档的工具&#xff0c;它可以帮助开发者生成易于阅读和理解的文档。Javadoc通过解析Java源代码中的注释&#xff0c;提取其…

英语角情景设计方案

背景介绍 在一个充满活力的清晨&#xff0c;项目团队汇集在线上会议中&#xff0c;准备开始他们定期的项目审查会议。团队成员不仅包括项目经理&#xff08;PM&#xff09;、客户代表&#xff0c;还有会计&#xff08;AM&#xff09;、设计师、前端开发者、后端开发者以及测试…

【CSS】background-size属性的作用是什么,怎么使用

background-size属性的作用&#xff1a; background-size属性在CSS中用于设置背景图像的尺寸。在CSS3之前&#xff0c;背景图片的尺寸是由图片的实际尺寸决定的。而在CSS3中&#xff0c;background-size属性允许我们规定背景图片的尺寸&#xff0c;这使得我们能够在不同的环境…