Spring源码中是如何使用设计模式六大原则的

设计模式的六大原则,通常指的是SOLID原则,它们是面向对象设计中用于提高代码可维护性、灵活性和可扩展性的五个指导原则,学习六大原则,可以让你的代码变得高级而优雅,今天的内容 V 哥结合 Spring源码中如何运用六大原则来具体讲解,希望能给你带来帮助:

  1. 单一职责原则(Single Responsibility Principle, SRP):一个类应该只有一个引起它变化的原因。
  2. 开闭原则(Open-Closed Principle, OCP):软件实体应该对扩展开放,对修改关闭。
  3. 里氏替换原则(Liskov Substitution Principle, LSP):子类对象必须能够替换掉它们的父类对象,而不影响程序的行为。
  4. 接口隔离原则(Interface Segregation Principle, ISP):客户端不应该依赖于它不使用的接口。
  5. 依赖倒置原则(Dependency Inversion Principle, DIP):高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
  6. 迪米特法则(Law of Demeter):一个对象应该对其他对象有尽可能少的了解。

在Spring框架中,这些原则得到了广泛应用,下面 V 哥一一详细解释 Spring框架源码中是如何运用的。

1. 单一职责原则

在Spring框架中,单一职责原则(SRP)的应用非常广泛,它体现在框架的许多组件和类的设计中。以下是通过Spring框架的BeanPostProcessor接口的一个例子来说明如何运用单一职责原则。

单一职责原则的定义

根据单一职责原则,一个类应该只有一个引起它变化的原因,即一个类应该只负责一项职责。

Spring中的BeanPostProcessor接口

BeanPostProcessor接口是一个用于在Bean的初始化过程中进行自定义处理的钩子(hook)。它提供了两个方法:postProcessBeforeInitialization和postProcessAfterInitialization。这两个方法分别在Bean初始化之前和之后调用,允许开发者插入自定义逻辑。

示例:自定义日志记录BeanPostProcessor

假设我们想要创建一个自定义的BeanPostProcessor来记录所有Bean的初始化日志。根据单一职责原则,这个BeanPostProcessor的职责就是记录日志,不应该包含其他业务逻辑。

public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// 在Bean初始化之前记录日志System.out.println("Before initializing bean: " + beanName);return bean; // 返回原始Bean以继续初始化过程}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// 在Bean初始化之后记录日志System.out.println("After initializing bean: " + beanName);return bean; // 返回原始Bean}
}

注册BeanPostProcessor

接下来,我们需要将这个BeanPostProcessor注册到Spring的上下文中,以便它可以被调用。

@Configuration
public class AppConfig {@Beanpublic MyBeanPostProcessor myBeanPostProcessor() {return new MyBeanPostProcessor();}
}

分析

在这个例子中,MyBeanPostProcessor类遵循了单一职责原则,因为它只负责一件事情:记录日志。这个类没有涉及到其他业务逻辑,如数据访问、业务计算等。这种设计使得MyBeanPostProcessor类非常专注于它的职责,易于理解和维护。

此外,Spring框架本身也遵循了单一职责原则。例如,ApplicationContext负责整个应用上下文的生命周期管理,BeanFactory负责Bean的创建和管理,而BeanPostProcessor则专注于Bean生命周期中的扩展点。每个接口和类都有明确的职责,这有助于保持代码的清晰和模块化。

通过这种方式,Spring框架的源码实现了高度的模块化和可维护性,使得开发者可以轻松地扩展和定制框架的行为。

2. 开闭原则

开闭原则(Open-Closed Principle, OCP)是说软件实体应当对扩展开放,对修改封闭。这意味着设计时应当使软件模块易于扩展,但是不需要修改现有代码就能添加新功能。

Spring框架在多个方面运用了开闭原则,以下是一些示例:

1. 扩展点 - 接口和抽象类

Spring框架定义了许多接口和抽象类作为扩展点,允许开发者实现这些接口或继承这些抽象类来扩展框架功能,而不需要修改框架本身的代码。

示例: ApplicationContext 接口及其实现类允许开发者通过实现不同的上下文来扩展Spring的IoC容器功能。

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource {// 定义了获取Bean等方法
}

开发者可以创建自定义的ApplicationContext实现来添加特定功能。

2. 策略模式 - 多个实现类

Spring框架使用策略模式允许在运行时根据不同的条件选择不同的行为。

示例: BeanPostProcessor 接口有多个实现类,每个类实现不同的处理逻辑。

public interface BeanPostProcessor {Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

开发者可以添加自己的BeanPostProcessor实现来扩展Bean的初始化过程。

3. 装饰者模式 - 增强功能

Spring AOP使用装饰者模式来增强方法的执行,允许开发者在不修改原有方法实现的情况下添加额外功能。

示例: 使用@Aspect注解的类可以定义切面,通过这些切面可以在不修改业务逻辑代码的情况下添加日志、事务管理等功能。

@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void beforeServiceMethod(JoinPoint joinPoint) {// 记录日志}
}

4. 观察者模式 - 事件发布和监听

Spring框架使用观察者模式来实现事件的发布和监听机制,允许在不修改事件源代码的情况下添加新的事件监听器。

示例: ApplicationEventPublisher 接口允许发布事件,而ApplicationListener 接口允许监听事件。

public interface ApplicationEventPublisher {void publishEvent(ApplicationEvent event);
}public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {void onApplicationEvent(E event);
}

开发者可以实现ApplicationListener接口来响应应用程序中的事件。

5. 依赖注入 - 灵活配置

Spring的依赖注入允许在不修改类代码的情况下,通过配置来改变类的行为。

示例: 通过XML配置或注解来注入不同实现的Bean。

<!-- XML配置示例 -->
<bean id="myService" class="com.example.service.MyServiceImpl"/>

或者使用注解:

@Service
public class MyService {// ...
}

在上述示例中,MyServiceImpl类可以被任何实现了MyService接口的类所替换,只需更改配置,而不需要修改使用MyService的代码。

分析

Spring框架通过提供清晰的接口和抽象类作为扩展点,允许开发者扩展其功能而不必修改现有代码,这正是开闭原则的体现。此外,Spring的AOP、事件机制和依赖注入等特性,都是遵循开闭原则设计的,它们提供了强大的扩展能力,同时保持了代码的封闭性,使得Spring能够适应不断变化的需求。

3. 里氏替换原则

里氏替换原则(Liskov Substitution Principle, LSP)指出子类型必须能够替换掉它们的父类型,而不影响程序的行为。在Spring框架中,里氏替换原则主要通过接口和抽象类的多态性来实现。以下是Spring框架中运用里氏替换原则的一些示例:

示例 1:使用JdbcTemplate的自定义扩展

Spring的JdbcTemplate是一个用于简化数据库操作的类。它提供了一个抽象的模板方法,可以被任何继承自它的子类所扩展。

public class MyCustomJdbcTemplate extends JdbcTemplate {@Overridepublic <T> T queryForObject(String sql, Object[] args, RowMapper<T> rowMapper) {// 自定义查询逻辑return super.queryForObject(sql, args, rowMapper);}
}

在这个示例中,MyCustomJdbcTemplate继承自JdbcTemplate并重写了queryForObject方法。根据里氏替换原则,MyCustomJdbcTemplate可以在任何使用JdbcTemplate的地方使用,而不需要修改使用它的代码。

示例 2:Spring的事件监听器

Spring的事件发布机制允许开发者发布和监听应用程序事件。ApplicationListener接口定义了事件监听器的行为。

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {void onApplicationEvent(E event);
}

开发者可以实现ApplicationListener接口来创建自定义的事件监听器:

@Component
public class MyCustomEventListener implements ApplicationListener<ApplicationEvent> {@Overridepublic void onApplicationEvent(ApplicationEvent event) {// 事件处理逻辑}
}

根据里氏替换原则,MyCustomEventListener可以替换任何实现了ApplicationListener接口的类,因为它遵循了接口定义的契约。

示例 3:Spring的拦截器

Spring的拦截器HandlerInterceptor用于在请求处理之前和之后执行自定义逻辑。

public interface HandlerInterceptor {boolean preHandle(HttpRequest request, HttpResponse response, Object handler) throws Exception;void postHandle(HttpRequest request, HttpResponse response, Object handler) throws Exception;void afterCompletion(HttpRequest request, HttpResponse response, Object handler, Exception ex) throws Exception;
}

开发者可以创建自定义的拦截器实现:

public class MyCustomInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 预处理逻辑return true;}// 实现其他方法...
}

MyCustomInterceptor遵循了HandlerInterceptor接口的契约,因此可以在任何需要拦截器的地方使用,满足里氏替换原则。

分析

在Spring框架中,里氏替换原则的运用主要体现在以下几个方面:

  • 多态性:通过接口和抽象类的多态性,Spring允许开发者实现自定义行为而不影响其他代码。
  • 扩展性:开发者可以实现或继承Spring的类和接口来扩展功能,同时保持与现有代码的兼容性。
  • 契约:接口和抽象类定义了清晰的契约,实现这些契约的子类必须保证不改变原有行为。

通过这种方式,Spring框架的设计允许高度的灵活性和可扩展性,同时保持代码的稳定性和可维护性。

4. 接口隔离原则

接口隔离原则(Interface Segregation Principle, ISP)指出客户端不应该依赖它不使用的方法。一个类对一个接口的依赖应该被限制为它真正需要的方法。在Spring框架中,接口隔离原则体现在多个方面,以下是一些示例:

示例 1:Spring的事件处理接口

在Spring框架中,事件处理相关的接口被设计得非常具体,以满足不同的使用场景。

public interface ApplicationEvent {// 事件相关的方法
}public interface ApplicationListener<E extends ApplicationEvent> {void onApplicationEvent(E event);
}public interface ContextRefreshedEvent extends ApplicationEvent {// 上下文刷新事件相关的方法
}

在这个例子中,ApplicationListener接口仅包含处理事件的方法,而不是一个包含多种类型事件处理方法的大接口。这样,实现ApplicationListener的类只需要关注它们感兴趣的事件类型,遵循接口隔离原则。

示例 2:Spring的数据访问异常层次结构

Spring为不同类型的数据访问操作提供了不同的异常类,而不是使用一个通用的异常类。

public class DataAccessException extends RuntimeException {// 数据访问异常基类
}public class DataAccessResourceFailureException extends DataAccessException {// 资源访问失败异常
}public class DataIntegrityViolationException extends DataAccessException {// 数据完整性违反异常
}

通过这种方式,调用者只需要捕获它们关心的异常类型,而不是一个大而全的异常类。

示例 3:Spring的事务管理接口

Spring提供了多个事务管理接口,每个接口关注事务管理的不同方面。

public interface PlatformTransactionManager {TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;void commit(TransactionStatus status);void rollback(TransactionStatus status);
}public interface TransactionDefinition {// 定义事务属性的方法
}public interface TransactionStatus {// 表示事务状态的方法
}

在这个例子中,PlatformTransactionManager接口提供了事务管理的方法,而TransactionDefinition和TransactionStatus接口分别定义了事务的属性和状态。这样,使用事务的代码只需要与它们真正需要的接口交互。

示例 4:Spring的Web MVC

Spring的Web MVC框架提供了多个接口来处理不同类型的请求处理逻辑。

public interface Controller {// 控制器的基础方法
}public interface LastModified {long getLastModified();
}public interface SessionStatus {void setComplete();
}public interface ModelAndView {// 处理模型和视图的方法
}

开发者可以根据需要实现Controller接口,并根据特定需求选择性实现LastModified或SessionStatus接口。

分析

Spring框架通过以下方式运用接口隔离原则:

  • 细粒度接口:Spring提供了细粒度的接口,每个接口只包含特定的方法集合,以满足特定的客户端需求。
  • 定制化实现:开发者可以根据需要实现特定的接口,而不需要实现一个包含许多不需要方法的大接口。
  • 灵活性和可维护性:接口隔离原则提高了系统的灵活性和可维护性,因为每个接口都有明确的责任,修改一个接口不会影响其他接口。

通过这种方式,Spring框架的设计允许开发者编写松耦合、高内聚的代码,使得系统更加模块化和易于扩展。

5. 依赖倒置原则

依赖倒置原则(Dependency Inversion Principle, DIP)是SOLID原则中的"D",它指出高层模块不应该依赖低层模块,两者都应该依赖于抽象(接口或抽象类)。Spring框架在多个方面运用了依赖倒置原则,以下是一些示例和分析:

示例 1:依赖注入(DI)

Spring框架的核心特性之一是依赖注入,它允许将组件的依赖关系注入到组件中,而不是让组件自己查找或创建依赖。这种方式使得组件依赖于抽象(接口或抽象类),而不是具体的实现。

public class UserService {private UserRepository userRepository;@Autowiredpublic UserService(UserRepository userRepository) {this.userRepository = userRepository;}// 使用userRepository执行业务逻辑
}

在这个例子中,UserService依赖于UserRepository接口,而不是任何具体的实现。这样,如果需要替换UserRepository的具体实现,只需要更改Spring的配置,而不需要修改UserService的代码。

示例 2:JdbcTemplate

JdbcTemplate是一个数据访问抽象,它允许开发者编写数据库操作代码而不需要依赖于特定的数据库操作实现。

public class JdbcTemplate extends DataSourceUtils {// ...public <T> List<T> query(String sql, RowMapper<T> rowMapper) {// 使用DataSource执行查询操作}
}

开发者可以使用JdbcTemplate来编写数据库操作,而不需要依赖于具体的DataSource实现。

示例 3:Spring的策略模式

Spring框架使用策略模式来允许开发者在运行时选择不同的行为。例如,BeanPostProcessor接口允许开发者实现自定义的Bean生命周期处理器。

public interface BeanPostProcessor {Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

开发者可以实现BeanPostProcessor接口来定义自己的处理逻辑,Spring容器将调用这些接口方法而不是具体的实现。

示例 4:Spring的Web MVC

在Spring的Web MVC框架中,Controller接口定义了请求处理的方法,开发者可以实现这个接口来创建自定义的控制器。

public interface Controller {ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}

通过实现Controller接口,开发者可以编写处理HTTP请求的逻辑,而不需要依赖于具体的请求处理实现。

分析

Spring框架通过以下方式运用依赖倒置原则:

  • 抽象化依赖:Spring鼓励开发者对接口编程,而不是对具体实现编程。这减少了模块间的耦合性。
  • 灵活性和可扩展性:通过依赖抽象,Spring框架提高了应用程序的灵活性和可扩展性。当需要替换组件的具体实现时,不需要修改依赖于它们的代码。
  • 控制反转(IoC):Spring的IoC容器管理了组件的创建和依赖关系的注入,这体现了依赖倒置原则,因为组件的依赖不是由组件自己控制的,而是由容器控制的。

通过运用依赖倒置原则,Spring框架提供了一个灵活、可扩展的编程模型,使得开发者能够轻松地替换组件实现,而不影响其他部分的代码。

6. 迪米特法则

迪米特法则(Least Knowledge Principle, LKP),也称为最少知识原则,主张一个对象应该对其他对象有尽可能少的了解,只与直接的朋友通信。在Spring框架中,迪米特法则主要通过控制组件之间的耦合度来实现,以下是一些示例和分析:

示例 1:Spring的依赖注入(DI)

Spring的依赖注入机制遵循迪米特法则,因为它允许组件声明它们的依赖关系,但是不负责获取依赖对象的实现。Spring容器负责将依赖注入到组件中。

@Component
public class UserServiceImpl implements UserService {private UserRepository userRepository; // 声明依赖,但不直接获取实现@Autowiredpublic void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}// 使用userRepository执行业务逻辑
}

在这个例子中,UserServiceImpl只与UserRepository有直接的交互,它不关心UserRepository的具体实现细节,这符合迪米特法则。

示例 2:Spring的AOP

Spring的AOP模块允许开发者定义切面(advice)和切入点(pointcut),在不修改业务逻辑代码的情况下增加额外的行为。

@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.service.*.*(..))")public void logBeforeServiceMethod(JoinPoint joinPoint) {// 日志记录逻辑}
}

在这个例子中,LoggingAspect只与JoinPoint交互,它不需要了解目标对象的内部结构或其它切面的实现。

示例 3:Spring的MVC

在Spring的MVC框架中,控制器(Controller)只与HttpServletRequest和HttpServletResponse交互,不直接与用户会话或其它Web组件交互。

@Controller
public class UserController {@GetMapping("/users")public String listUsers(Model model, HttpServletRequest request) {List<User> users = userService.listUsers();model.addAttribute("users", users);return "userList";}
}

控制器只与Model和HttpServletRequest交互,不直接与用户会话或其它Web组件交互,这减少了组件之间的耦合度。

示例 4:Spring的事件发布机制

Spring的事件发布机制允许组件发布事件而不需要知道谁是监听者,同样,事件监听者也不需要知道事件的来源。

@Component
public class UserEventPublisher {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void publishUserEvent(User user) {UserCreatedEvent event = new UserCreatedEvent(this, user);eventPublisher.publishEvent(event);}
}@Component
public class UserEventListener implements ApplicationListener<UserCreatedEvent> {@Overridepublic void onApplicationEvent(UserCreatedEvent event) {// 处理用户创建事件}
}

UserEventPublisher只与ApplicationEventPublisher交互,而UserEventListener只与UserCreatedEvent交互,它们之间没有直接的耦合。

分析

Spring框架通过以下方式运用迪米特法则:

  • 减少直接交互:组件之间的交互通过抽象和间接的方式进行,减少了直接的依赖关系。
  • 使用中间件:Spring使用各种中间件(如IoC容器、AOP框架、MVC框架等)来减少组件之间的直接耦合。
  • 声明式编程:Spring鼓励使用声明式编程,如使用注解或配置文件来声明依赖关系,而不是在代码中硬编码。

通过运用迪米特法则,Spring框架提高了组件的内聚性和降低了组件之间的耦合度,使得系统更加模块化和易于维护。

最后

V 哥建议,通过 Spring 源码来学习设计模式的六大原则具体应用,不仅能够掌握基本的概念,还能掌握实际应用场景中是如何使用的,正所谓知其然知其所以然,这样学习 JAVA 才带劲。如果文章内容对你有帮助,客官,点个赞再走呗,你的支持是 V 哥原创写作的最大动力,关注威哥爱编程,JAVA 之路咱们一起搀扶前行,结伴同行,才能走得更远。

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

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

相关文章

偏微分方程算法之抛物型方程差分格式编程示例四(Richardson外推)

目录 一、研究问题 二、C++代码 三、结果分析 一、研究问题 已知其精确解为。分别取以下三种步长: ①

流程引擎框架

SpiffWorkflow python 流程引擎框架哪个好 Camunda 核心表介绍 https://zhuanlan.zhihu.com/p/645786758 camunda流程引擎基本使用&#xff08;笔记&#xff09; https://blog.csdn.net/weixin_46949627/article/details/129255647 python连接FastDfs服务封装类 https://blog.c…

树形dp,CF 1926 G - Vlad and Trouble at MIT

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - G - Codeforces 二、解题报告 1、思路分析 考虑每个结点最终状态只可能为和P连通或者和S连通 我们我们自然而然的将问题划分为这样的状态 f[x][0]代表结点x和P连通需要割掉最少的边 f[x][1]代…

Windows Server配置NFS,做ESXI共享存储

1:登录wINDOWS系统&#xff0c;点击添加角色和功能。 2:根据向导提示&#xff0c;一路下一步。在服务器角色中选择文件和存储服务器在文件和iSCSI服务中勾选NFS服务器。 3&#xff1a;按照提示一路下一步&#xff0c;安装NFS。 4&#xff1a;安装完成后关闭安装界面。 5&#x…

代码随想录算法训练营第六十五天 | 岛屿数量 深搜、岛屿数量 广搜、岛屿的最大面积

岛屿数量 深搜 题目链接&#xff1a;99. 岛屿数量 文字讲解&#xff1a;99. 岛屿数量 | 代码随想录 解题思路 本题已经说明&#xff0c;只有水平方向和竖直方向才能组成岛屿 本题思路&#xff0c;是遇到一个没有遍历过的节点陆地&#xff0c;计数器就加一&#xff0c;然后把…

为电脑小白推荐的5款实用工具软件

​ 电脑上的各类软件有很多&#xff0c;除了那些常见的大众化软件&#xff0c;还有很多不为人知的小众软件&#xff0c;专注于实用功能&#xff0c;简洁干净、功能强悍。 1.磁盘空间分析——TreeSize Free ​ TreeSize Free是一款免费的磁盘空间分析工具&#xff0c;能够扫描…

Sip协议(四) -注册流程

Sip协议(四) -注册流程 本文主要介绍下sip协议中, agent的注册流程. 一: 流程图 简单的流程图如下: agent发起注册fs 返回401 ,并携带WWW-Authenticateagent第二次发起注册,增加Authorizationfs返回授权成功, 或者失败. 二: sip流程 发起注册REGISTER 首先agent发起注册请求…

重磅!鹅厂大牛带你30分钟玩转AI智能结对编程!

在大模型时代&#xff0c;人工智能技术的突破性进展正重塑着软件开发的面貌。AI的融入不仅优化了代码编写过程&#xff0c;更开启了智能编程的新纪元&#xff0c;为开发者带来了前所未有的工作效率和创新可能。AI结对编程不仅能够极大提升研发效率&#xff0c;还能通过智能分析…

Java基础入门day65

day65 web项目 页面设计 仿照小米官网&#xff0c;将首页保存到本地为一个html页面&#xff0c;再将html页面保存为jsp页面&#xff0c;在项目中的web.xml文件中配置了欢迎页 <welcome-file-list><welcome-file>TypesServlet</welcome-file> </welcome-…

linux源码编译

1/进入源码目录 cd linux.4.9.1 2. 从当前机器的启动目录拷贝配置信息到源代码目录。这步操作的意思是我们编译内核的配置采用用当前环境一致的配置。 cp -v /boot/config-$(uname -r) .config 3.配置界面 make menuconfig 4/先编译所有模块&#xff0c;确保正确 make -j…

【查缺补漏】python

python查缺补漏 底板除 还有一种除法是//&#xff0c;称为地板除&#xff0c;两个整数的除法仍然是整数&#xff1a; >>> 10 // 3 3你没有看错&#xff0c;整数的地板除//永远是整数&#xff0c;即使除不尽。要做精确的除法&#xff0c;使用/就可以。 因为//除法只…

rsa加签验签C#和js、java、微信小程序互通

js实现rsa加签验签 https://github.com/kjur/jsrsasign 11.1.0版本 解压选择需要的版本&#xff0c;这里选择all版本了 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>JS RSA加签验签</title&g…

有趣网站分享 - 生成 O‘Reilly 类型封面

文章目录 网站介绍效果 网站介绍 –> O’RLY 封面工厂 https://orly.nanmu.me 你可以… 设置文本内容 选择图片 选择颜色 效果 2024-06-20&#xff08;四&#xff09;

机器人----控制方式

位置控制 点位控制 点到点--PTP 只关心起点和目标点&#xff0c;不关心走过的轨迹。 连续轨迹控制 CP(continus path) eg&#xff1a;焊接&#xff0c;切割。 力控制 使用多大的力进行控制。 eg:用多大的力写字。

2.java pom.xml 添加配置说明

目录 1项目坐标&#xff1a; 2项目依赖&#xff1a; 3项目构建配置&#xff1a; 4项目属性&#xff1a; 5.项目信息&#xff1a; 6.项目分发管理&#xff1a; 7.项目插件配置&#xff1a; 8.项目依赖管理&#xff1a; pom.xml 是 Maven 项目的核心配置文件&#xff0c…

LSTM学习资料

这里写自定义目录标题 1.一个大二学生对LSTM的理解 https://www.bilibili.com/video/BV1jp421d7f8/?spm_id_from333.999.0.0&vd_sourcecc2da879c044059d9838f660bcaf4664 2.【LSTM从入门到精通】2小时带你掌握LSTM算法&#xff01; https://www.bilibili.com/video/BV1yb4…

Vim入门教程

Vim是一个高度可配置的文本编辑器&#xff0c;用于创建和修改各种类型的文本文件。以下是一些基本的Vim使用示例&#xff0c;展示如何在Vim中进行编辑和操作。 1. 打开和保存文件 打开一个名为example.txt的文件&#xff1a; vim example.txt 打开多个文件&#xff0c;使用大…

前端网页开发学习(HTML+CSS+JS)有这一篇就够!

目录 HTML教程 ▐ 概述 ▐ 基础语法 ▐ 文本标签 ▐ 列表标签 ▐ 表格标签 ▐ 表单标签 CSS教程 ▐ 概述 ▐ 基础语法 ▐ 选择器 ▐ 修饰文本 ▐ 修饰背景 ▐ 透明度 ▐ 伪类 ▐ 盒子模型 ▐ 浮动 ▐ 定位 JavaScript教程 ▐ 概述 ▐ 基础语法 ▐ 函数 …

契约锁电子签章平台 add 远程命令执行漏洞复现(XVE-2023-23720)

0x01 产品简介 契约锁电子签章平台是上海亘岩网络科技有限公司推出的一套数字签章解决方案。契约锁为中大型组织提供“数字身份、电子签章、印章管控以及数据存证服务”于一体的数字可信基础解决方案,可无缝集成各类系统,让其具有电子化签署的能力,实现组织全程数字化办公。通…

还在为Android开发找不到图片测试资源发愁吗? DummyImage来助你加速开发

使用 DummyImage 模拟电影应用数据 在开发和测试过程中&#xff0c;模拟数据是不可或缺的工具。它可以帮助我们在没有真实数据的情况下测试应用程序的功能和性能。本文将介绍如何使用 [DummyImage]https://dummyimage.com生成占位符图像来模拟电影应用的数据&#xff0c;并深入…