DAY03_Spring—自动装配注解模式优化XML文件

目录

  • 1 Spring注解模式
    • 1.1 自动装配
      • 1.1.1 说明
      • 1.1.2 配置规则
    • 1.2 注解模式
      • 1.2.1 关于注解的说明
      • 1.2.2 注解使用原理
      • 1.2.3 编辑配置文件
      • 1.2.4 属性注解
    • 1.3 实现MVC结构的纯注解开发
      • 1.3.1 编写java代码
      • 1.3.2 编辑xml配置文件
      • 1.3.3 编写测试类
      • 1.3.4 关于注解说明
      • 1.3.5 关于Spring工厂模式说明
    • 1.4 优化xml配置文件
      • 1.4.1配置类介绍
      • 1.4.2编辑配置类
      • 1.4.3 编辑测试代码
    • 1.5 Spring注解模式执行过程
    • 1.6 Spring中常见问题
      • 1.6.1 接口多实现类情况说明
      • 1.6.2 案例分析
    • 1.7 Spring容器管理业务数据@Bean注解
      • 1.7.1 @Bean作用
      • 1.7.2 编辑UserController
    • 1.8 Spring动态获取外部数据
      • 1.8.1 编辑properties文件
      • 1.8.2 编辑配置类

1 Spring注解模式

1.1 自动装配

1.1.1 说明

Spring基于配置文件 为了让属性(对象的引用)注入更加的简单.则推出了自动装配模式.

  • 根据名称自动装配
  • 根据类型自动装配

1.1.2 配置规则

<?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"><!--1.构建user对象--><bean id="user" class="com.jt.pojo.User"><!--根据name属性查找对象的setId()方法 将value当作参数调用set方法完成赋值--><property name="id" value="100"/><!--<property name="name" value="&lt;范冰冰&gt;"/>--><property name="name"><value><![CDATA[<范冰冰>]]></value></property></bean><!--2.构建Dao对象根据面向接口编程Id:接口的名称class:实现类的包路径--><bean id="userDao" class="com.jt.dao.UserDaoImpl"/><!--3.构建Service自动装配: 程序无需手动的编辑property属性autowire="byName" 根据属性的名称进行注入1.找到对象的所有的set方法 setUserDao()2.setUserDao~~~~set去掉~~~UserDao~~~~首字母小写~~~userDao属性3.Spring会根据对象的属性查询自己维护的Map集合,根据userDao名称,查找Map中的Key与之对应,如果匹配成功.则能自动调用set方法实现注入(必需有set方法)autowire="byType"1.找到对象的所有的set方法 setUserDao()2.根据set方法找到方法中参数的类型UserDao.class3.Spring根据自己维护对象的Class进行匹配.如果匹配成功则实现注入(set方法)autowire:规则 如果配置了byName则首先按照name查找,如果查找不到则按照byType方式查找首选类型查找byType--><bean id="userService" class="com.jt.service.UserServiceImpl" autowire="byName"><!--<property name="userDao" ref="userDao"/>--></bean><!--4.构建Controller--><bean id="userController" class="com.jt.controller.UserController" autowire="byType"><!--<property name="userService" ref="userService"/><property name="user" ref="user"/>--></bean>
</beans>

1.2 注解模式

1.2.1 关于注解的说明

Spring为了简化xml配置方式,则研发注解模式.

Spring为了程序更加的严谨,通过不同的注解标识不同的层级 但是注解的功能一样

  • @Controller
    • 用来标识Controller层的代码 相当于将对象交给Spring管理
  • @Service
    • 用来标识Service层代码
  • @Repository
    • 用来标识持久层
  • @Component
    • 万用注解

1.2.2 注解使用原理

/*** <bean id="类名首字母小写~~userDaoImpl"  class="UserDaoImpl.class" />* 如果需要修改beanId则手动添加value属性即可*/
@Repository(value = "userDao")
public class UserDaoImpl implements UserDao{@Overridepublic void addUser(User user) {System.out.println("链接数据库执行insert into :"+user);}
}

1.2.3 编辑配置文件

<?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"><!--1.构建user对象--><bean id="user" class="com.jt.pojo.User"><property name="id" value="100"></property><property name="name"><value><![CDATA[<范冰冰>]]></value></property></bean><!--2.让注解生效,开启包扫描包路径特点: 给定包路径,则自动扫描同包及子孙包中的类base-package: 根据指定的包路径 查找注解写方式: 多个包路径 使用,号分隔--><!--<context:component-scan base-package="com.jt.controller,com.jt.service,com.jt.dao"></context:component-scan>--><context:component-scan base-package="com.jt"></context:component-scan><!--业务需求1: 只想扫描@controller注解属性说明: use-default-filters="true"默认规则 :true  表示可以扫描其他注解:false  按照用户指定的注解进行加载,默认规则不生效--><context:component-scan base-package="com.jt" use-default-filters="false"><!--通过包扫描 不可以加载其他的注解 只扫描Controller注解--><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan><!--业务需求2: 不想扫描@controller注解--><context:component-scan base-package="com.jt"><!--通过包扫描 可以加载其他的注解 排除Controller注解--><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/></context:component-scan>
</beans>

1.2.4 属性注解

  • @Autowired: 可以根据类型/属性名称进行注入 首先按照类型进行注入如果类型注入失败,则根据属性名称注入
  • @Qualifier: 如果需要按照名称进行注入,则需要额外添加@Qualifier
  • @Resource(type = “xxx.class”,name=“属性名称”)
  • 关于注解补充:
    • 由于@Resource注解 是由java原生提供的,不是Spring官方的.所以不建议使用

上述的属性的注入在调用时 自动的封装了Set方法,所以Set方法可以省略不写

import com.jt.dao.UserDao;
import com.jt.pojo.User;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService{@Autowiredprivate UserDao userDao;//基于Spring注入dao  面向接口编程// public void setUserDao(UserDao userDao) {//     this.userDao = userDao;//}@Overridepublic void addUser(User user) {String name = user.getName() + "加工数据";user.setName(name);userDao.addUser(user);}
}

1.3 实现MVC结构的纯注解开发

1.3.1 编写java代码

public class User {//自动装配不能注入简单属性private Integer id;private String username;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +'}';}
}
import com.jt.pojo.User;public interface UserDao {void addUser(User user);
}
import com.jt.pojo.User;
import org.springframework.stereotype.Repository;@Repository
public class UserDaoImpl implements UserDao {@Overridepublic void addUser(User user) {System.out.println("新增用户的数据" + user);}
}
import com.jt.pojo.User;public interface UserService {void addUser(User user);
}
import com.jt.dao.UserDao;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Autowired //根据类型进行注入 如需要根据属性名称注入需要添加@Qualifier注解————必须按照名称进行匹配private UserDao userDao;@Overridepublic void addUser(User user) {userDao.addUser(user);}
}
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController {@Autowiredprivate UserService userService;public void addUser() {User user = new User();user.setId(101);user.setUsername("王昭君|不知火舞");userService.addUser(user);}
}

1.3.2 编辑xml配置文件

<?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="com.jt"/>
</beans>

1.3.3 编写测试类

@Testpublic void test01(){ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");UserController userController = context.getBean(UserController.class);userController.addUser();}
  • 测试结果

在这里插入图片描述

1.3.4 关于注解说明

  • 注解作用
    • 一些复杂的程序 以一种低耦合度的形式进行调用
  • 元注解:
    • @Target({ElementType.TYPE}) 标识注解对谁有效 type:类 method:方法有效
    • @Retention(RetentionPolicy.RUNTIME) 运行期有效(大)
    • @Documented 该注解注释编译到API文档中.
  • 由谁加载
    • 由Spring内部的源码负责调用.
      在这里插入图片描述

1.3.5 关于Spring工厂模式说明

  • Spring源码中创建对象都是采用工厂模式
    • 接口:BeanFactory(顶级接口)
  • Spring开发中需要手动的创建对象时
    • 一般采用 FactoryBean(业务接口)
  • 关于bean对象注入问题说明 一般需要检查注解是否正确配置
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.jt.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userController': Unsatisfied dependency expressed through field 'userService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.jt.service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

1.4 优化xml配置文件

1.4.1配置类介绍

随着软件技术发展,xml配置文件显得臃肿 不便于操作,所以Spring后期提出了配置类的思想

将所有的配置文件中的内容,写到java类中.

1.4.2编辑配置类

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration //标识我是一个配置类 相当于application.xml
@ComponentScan("com.jt") //如果注解中只有value属性 则可以省略
public class SpringConfig {}

1.4.3 编辑测试代码

@Testpublic void testAnno(){ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);UserController userController = context.getBean(UserController.class);userController.addUser();}
  • 测试结果

在这里插入图片描述

1.5 Spring注解模式执行过程

  1. 当程序启动Spring容器时 AnnotationConfigApplicationContext 利用beanFactory实例化对象
  2. 根据配置类中的包扫描开始加载指定的注解(4个). 根据配置文件的顺序依次进行加载
    在这里插入图片描述
  3. 当程序实例化Controller时,由于缺少Service对象,所以挂起线程 继续执行后续逻辑.
    当构建Service时,由于缺少Dao对象,所以挂起线程 继续执行后续逻辑.
    当实例化Dao成功时,保存到Spring所维护的Map集合中. 执行之前挂起的线程.
    所以以此类推 所有对象实现封装.最终容器启动成功
    在这里插入图片描述
  4. 根据指定的注解/注入指定的对象.之后统一交给Spring容器进行管理.最终程序启动成功.

1.6 Spring中常见问题

1.6.1 接口多实现类情况说明

Spring中规定 一个接口最好只有一个实现类.

  • 业务需求:
    • 要求给UserService接口提供2个实现类.

1.6.2 案例分析

  1. 编辑实现类A
    在这里插入图片描述
  2. 编辑实现类B
    在这里插入图片描述
  3. 实现类型的注入
import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;@Controller
public class UserController {/*** @Autowired: 首先根据属性的类型进行注入,* 如果类型不能匹配,则根据属性的名称进行注入.* 如果添加了@Qualifier("userServiceA") 则根据属性名称注入* 如果名称注入失败,则报错返回.*/@Autowired@Qualifier("userServiceB")private UserService userService;public void addUser() {User user = new User();user.setId(101);user.setUsername("王昭君|不知火舞");userService.addUser(user);}
}

1.7 Spring容器管理业务数据@Bean注解

1.7.1 @Bean作用

通过该注解,可以将业务数据实例化之后,交给Spring容器管理. 但是@Bean注解应该写到配置类中.

import com.jt.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration //标识我是一个配置类 相当于application.xml
@ComponentScan("com.jt") //如果注解中只有value属性 则可以省略
public class SpringConfig {/*1.Spring配置文件写法 <bean id="方法名称"  class="返回值的类型" />2.执行@Bean的方法 将方法名称当做ID,返回值的对象当做value 直接保存到Map集合中*/@Beanpublic User user(){User user = new User();user.setId(101);user.setUsername("Spring容器");return user;}
}

1.7.2 编辑UserController

import com.jt.pojo.User;
import com.jt.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;@Controller
public class UserController {/*** @Autowired: 首先根据属性的类型进行注入,* 如果类型不能匹配,则根据属性的名称进行注入.* 如果添加了@Qualifier("userServiceA") 则根据属性名称注入* 如果名称注入失败,则报错返回.*/@Autowired@Qualifier("userServiceA")private UserService userService;@Autowiredprivate User user;  //从容器中动态获取public void addUser() {userService.addUser(user);}
}
  • 测试结果

在这里插入图片描述

1.8 Spring动态获取外部数据

1.8.1 编辑properties文件

在这里插入图片描述

# 规则: properties文件
# 数据结构类型:  k-v结构
# 存储数据类型:  只能保存String类型
# 加载时编码格式: 默认采用ISO-8859-1格式解析 中文必然乱码
user.id=1001
# Spring容器获取的当前计算机的名称 所以user.name慎用
# user.name=你好啊哈哈哈
user.username=鲁班七号

1.8.2 编辑配置类

  • @PropertySource
    • 用法:
      • @PropertySource(“classpath:/user.properties”)
    • 说明:
      • @PropertySource 作用: 加载指定的pro配置文件 将数据保存到Spring容器中
  • @Value
    • java @Value(123) 将123值赋值给Id @Value("${user.id}") 在Spring容器中查找key=user.id的数据.通过${}语法获取
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;@Configuration //标识我是一个配置类 相当于application.xml
@ComponentScan("com.jt") //如果注解中只有value属性 则可以省略
//@PropertySource 作用: 加载指定的pro配置文件 将数据保存到Spring容器中
//encoding:指定字符集编码格式
@PropertySource(value = "classpath:/user.properties",encoding = "UTF-8")
public class SpringConfig {//定义对象属性 准备接收数据//@Value(123)   将123值赋值给Id//@Value("${user.id}")  在Spring容器中查找key=user.id的数据.通过${} 进行触发    @Value("${user.id}")@Value("${user.id}")private Integer id;@Value("${user.username}")private String username;/*1.Spring配置文件写法 <bean id="方法名称"  class="返回值的类型" />2.执行@Bean的方法 将方法名称当做ID,返回值的对象当做value 直接保存到Map集合中*/@Beanpublic User user(){User user = new User();user.setId(id);user.setUsername(username);return user;}
}
  • 测试结果

在这里插入图片描述

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

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

相关文章

Ubuntu20.4 Mono C# gtk 编程习练笔记(二)

界面设计习练后&#xff0c;下面写一些程序设计心得。 程序结构 先看一下程序总体结构&#xff0c;先在program.cs中找到main入口&#xff0c;在命名空间下是MainClass类&#xff0c;Main函数进入后首先建立应用程序环境 Application.Init&#xff0c;然后对MainWindow进行实…

【嘉立创EDA-PCB设计指南】3.网络表概念解读+板框绘制

前言&#xff1a;本文对网络表概念解读板框绘制&#xff08;确定PCB板子轮廓&#xff09; 网络表概念解读 在本专栏的上一篇文章【嘉立创EDA-PCB设计指南】2&#xff0c;将设计的原理图转为了PCB&#xff0c;在PCB界面下出现了所有的封装&#xff0c;以及所有的飞线属性&…

【开源】基于JAVA语言的智慧家政系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服务4.2 新增单条服务订单4.3 新增留言反馈4.4 小程序登录4.5 小程序数据展示 五、免责说明 一、摘要 1.1 项目介绍 基于微信小程序JAVAVueSpringBootMySQL的智慧家政系统&#xff0…

【Docker】安装 Nginx 容器并部署前后端分离项目

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Docker实战》。&#x1f3af;&#x1f3af; &…

GRU门控循环单元神经网络的MATLAB实现(含源代码)

在深度学习领域&#xff0c;循环神经网络&#xff08;RNN&#xff09;因其在处理序列数据方面的卓越能力而受到广泛关注。GRU&#xff08;门控循环单元&#xff09;作为RNN的一种变体&#xff0c;以其在捕捉时间序列长距离依赖关系方面的高效性而备受推崇。在本文中&#xff0c…

SpringBoot 中使用 Quartz 创建定时任务

文章目录 一、使用示例二、运行原理 一、使用示例 自定义 job&#xff1a; Slf4j public class MyJob extends QuartzJobBean {Overrideprotected void executeInternal(JobExecutionContext context) throws JobExecutionException {log.info("MyJob start...");l…

JavaWeb后端——Maven

maven主要服务于基于Java平台的项目构建、依赖管理和项目信息管理 maven项目对象模型简称POM&#xff0c; maven解决问题&#xff1a; 1. 添加第三方jar包&#xff0c;maven将 jar 包放在本地仓库中统一管理&#xff0c;使用时用坐标的方式引用即可 2. 解决 jar 包之间的依…

Facebook与环境保护:社交媒体的可持续发展

在当今社会&#xff0c;科技发展日新月异&#xff0c;而社交媒体作为数字时代的代表之一&#xff0c;正面临着巨大的责任与机遇。随着全球环境问题的凸显&#xff0c;社交媒体平台如Facebook也逐渐认识到自身在环保可持续发展中的角色。本文将深入探讨Facebook在环境保护方面的…

统计学-R语言-5.3

文章目录 前言分位数统计量的标准误总结 前言 本篇文章即为概率与分布的最后一篇文章。 分位数 分位数函数是累积分布函数的反函数。 p-分位数是具有这样性质的一个值&#xff1a;小于或等于它的概率为p。 根据定义&#xff0c;中位数即50%分位数。 分位数通常用于置信区间的…

vite 打包优化

✨专栏介绍 在当今数字化时代&#xff0c;Web应用程序已经成为了人们生活和工作中不可或缺的一部分。而要构建出令人印象深刻且功能强大的Web应用程序&#xff0c;就需要掌握一系列前端技术。前端技术涵盖了HTML、CSS和JavaScript等核心技术&#xff0c;以及各种框架、库和工具…

【机器学习实例讲解】机器学习-鸢尾花数据集多分类第02课

问题定义与理解&#xff1a; 明确机器学习任务的目标&#xff0c;是分类、回归、聚类、强化学习还是其他类型的问题。 确定业务背景和需求&#xff0c;了解所处理数据的现实意义。 数据收集&#xff1a; 根据任务目标从各种来源获取原始数据&#xff0c;可以是数据库、文件、…

Spring5深入浅出篇:Spring与工厂设计模式简介

Spring5深入浅出篇:Spring与工厂设计模式简介 什么是Spring Spring是⼀个轻量级的JavaEE解决⽅案&#xff0c;整合众多优秀的设计模式轻量级 1. 对于运⾏环境是没有额外要求的开源 tomcat resion jetty收费 weblogic websphere 2. 代码移植性⾼不需要实现额外接⼝JavaEE的解…

Bing AI:探索人工智能搜索引擎Bing Chat工具

Microsoft 更新了其搜索引擎 Bing&#xff0c;采用了由 OpenAI 的 GPT-4 模型提供支持的人工智能 &#xff08;AI&#xff09; 技术。 这意味着您现在可以与 Bing 聊天。而且&#xff0c;除了常规的链接列表外&#xff0c;搜索引擎还可以汇总互联网上的数据来回答您的问题。 …

架构篇04-复杂度来源:高性能

文章目录 单机复杂度集群的复杂度小结 从本篇开始&#xff0c;我们一起深入分析架构设计复杂度的 6 个来源&#xff0c;先来聊聊复杂度的来源之一高性能。 对性能孜孜不倦的追求是整个人类技术不断发展的根本驱动力。例如计算机&#xff0c;从电子管计算机到晶体管计算机再到集…

VL171 VL170配合LDR6020的type-c母座显示器方案

兼容基于VASEL控制引脚的10 Gbps USB3.2 Gen2和AM所有4通道视频&#xff0c;包括DP1.4 8.1 Gbps VL171配合LDR6020实现的type-c桌面显示器方案电路LDR6020是一个DRP的PD芯片&#xff0c;PD芯片与主机通讯完之后&#xff0c;通过PD芯片去控制VL171实现正反插与USB信号和DP信号的…

31 3D日历组件

效果演示 实现了一个3D文字旋转的效果&#xff0c;当鼠标悬停在容器上时&#xff0c;最后一个文字会旋转630度&#xff0c;而其他文字会逐渐旋转到水平面上方。 Code <div class"container"><div class"text" style"--j:0;"><sp…

MySQL -- Linux Ubuntu 环境安装MySQL数据库

注意&#xff1a;本篇所有命令均是在linux 服务器root账号下运行。 安装MySQL 安装 apt-get install mysql-server 启动mysql服务 systemctl start mysql查看mysql服务 systemctl status mysql 如下图所示&#xff0c;mysql服务正在运行 设置root密码 在第一次安装MyS…

【Redis】Redis如何做内存优化?

​ &#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Redis ⛳️ 功不唐捐&#xff0c;玉汝于成 ​ 目录 前言 正文 使用数据结构&#xff1a; 压缩对象&#xff1a; 过期策略&#xff1a; 分片&#xff1a; 使用持久化方式&#xff1a…

虚幻UE 材质-进阶边界混合之运行时虚拟纹理

之前在学习空山新雨后时对于边缘虚化过渡处理有很多技术 今天又要介绍一个边缘过渡的方法&#xff1a;运行时虚拟纹理 文章目录 前言一、运行时虚拟纹理二、使用步骤总结 前言 边缘过渡柔和的方式我们之前介绍了很多&#xff0c;但是效果也不是最好的。 像素偏移PDO和我们今天…

架构设计: 如何提供设计方案

面试时你是否常被问到这样的问题&#xff1a;“你之前是如何设计这个系统&#xff08;或子系统/模块/功能&#xff09;的&#xff1f;请介绍你的思路。” 很多研发同学在听到类似的面试题时&#xff0c;往往忽略“系统设计思路”关键词&#xff0c;而是陷入某个技术点细节里&a…