《参与中型项目,领略 Spring 魅力》
一、Spring 在中型项目中的魅力展现
Spring 框架以其强大的功能和灵活性,在中型项目中发挥着重要作用。它不仅简化了开发过程,还提高了代码的可维护性和可扩展性。
Spring 在中型项目中魅力十足,其优势主要体现在以下几个方面。
首先,Spring 框架的依赖注入机制极大地简化了开发过程。通过依赖注入,开发人员无需手动创建对象并管理它们之间的依赖关系,而是由 Spring 容器负责对象的创建和注入。这使得代码更加简洁、易于理解和维护。例如,使用 Java 和 Spring 重构服务之间的依赖关系,可以采用依赖注入的方式,将服务之间的依赖关系从代码中解耦出来,使得代码更加灵活和可测试。Spring 框架提供了依赖注入的支持,可以通过配置文件或注解的方式来实现。
其次,Spring 框架大量运用了设计模式,提高了代码的可维护性和可扩展性。设计模式是面向对象设计的通用解决方案,用于解决软件开发过程中的常见问题。Spring 框架在设计时大量借鉴和使用了设计模式,例如 IoC 容器实现了依赖注入,这是工厂模式和控制反转模式的结合。Spring 的配置文件和注解也体现了工厂模式和单例模式的思想。通过这种方式,Spring 框架不仅简化了应用程序的开发过程,还提高了代码的可维护性和可扩展性。例如,在 Mybatis 中,SqlSession 是一个接口,定义了对数据库的一大堆基本操作。创建 DefaultSqlSession 的过程比较复杂,如果每个需要 DefaultSqlSession 的实例的调用者都需要写这么一大串代码,那得写多少重复代码?万一创建过程有改动,我们得改多少个地方?所以我们会很自然的想到把它抽到一个公共的地方,每次需要他,就去公共的地方拿就行了。即使有改动,也只需改动这个公共方法即可。这就是工厂模式的体现。
此外,Spring 框架还提供了丰富的 API 和模块化的组件,可以快速构建出复杂的应用程序。其中最核心的组件是 Spring Core,它提供了依赖注入和面向切面编程等基础机制,使得我们可以更加轻松地管理对象之间的关系,从而降低代码的耦合度和复杂度。此外,Spring 还提供了许多有用的模块,例如 Spring MVC、Spring Data、Spring Security 等,可以帮助我们快速实现 Web 应用程序、访问数据库、处理安全问题等。
总之,Spring 框架在中型项目中具有强大的魅力,它简化了开发过程,提高了代码的可维护性和可扩展性,为开发人员提供了丰富的 API 和模块化的组件,是中型项目开发的理想选择。
二、Spring 的核心特性
1. 控制反转与依赖注入
- 介绍控制反转的概念,即创建对象的控制权反转到 Spring 框架上。
控制反转(Inversion of Control,缩写为 IoC),是面向对象编程的一种设计原则,可以用来减低计算机代码之间的耦合度。常见的方式叫做依赖注入(Dependency Injection,简称 DI),还有一种方式叫依赖查找。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
- 阐述依赖注入的实现方式,减少程序之间的耦合性。
当某个角色(可能是一个 Java 实例,调用者)需要另一个角色(另一个 Java 实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在 Spring 里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由 Spring 容器来完成,然后注入调用者,因此也称为依赖注入。依赖注入有两种:设值注入、构造注入。所谓依赖注入,是指程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部的注入。Spring 的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对 POJO 之间依赖关系的管理。
Spring 常用的三种依赖注入方式主要有:
- 基于注解的注入:使用注解注册 bean,有四种注解可以注册 bean,每种注解可以任意使用,只是语义上有所差异:@Component、@Repository、@Controller、@Service。装配 bean 时常用的注解有@Resource和@Autowired。
- 构造方法注入:在接受注入的类中定义一个构造方法,并在参数中定义需要注入的元素。
- set 注入:通过 set 方法,set 某一个具体实现类,或者在 xml 配置文件中配置。
2. @Import 的妙用
- 讲解如何通过 @Import 注解引入普通类和配置类。
在 Spring 框架中,@Import注解用于导入其他配置类或普通类,以便将它们注册为 Spring 上下文中的 Bean。
- 导入普通类:导入普通类非常简单,只需在@Import传入类的 Class 对象即可。
- 导入@Configuration配置类:导入配置类与导入普通类一样,在@Import注解中传入目标类的 Class 对象。
- 导入多个类:可以通过数组的方式一次性导入多个类。
- 使用ImportSelector:@Import还可以使用ImportSelector接口来动态选择要导入的类。
- 使用ImportBeanDefinitionRegistrar:@Import注解的另一种用法是导入实现了ImportBeanDefinitionRegistrar接口的类。这种方式允许你在注册 Bean 的过程中自定义 Bean 的定义,通常用于更复杂的场景。
- 说明引入 @Configuration 注解的配置类的复杂性。
本章节我们来探索 Spring 中一个常用的注解@Configuration。我们先来了解一下该注解的作用是:用来定义当前类为配置类。加了@Configuration的配置类内部,都会包含一个或多个@Bean注解的方法。Spring 会保证多次调用@Bean标注的工厂方法,不会重复产生新的对象,始终是同一个,这也贯彻了 Spring 的单例哲学。Spring 对@Configuration标识的类做了代理,从而进行功能的增强。对@Configuration的解析过程是在 spring 扫描类的时候进行的。Spring 把加了@Configuration注解的称为全配置类,其他的称为半配置类,两者判别标准是:是否加了@Configuration注解。
3. Conditional 注解家族
- 介绍 @ConditionalOnClass、@ConditionalOnBean、@ConditionalOnProperty 等注解的强大之处。
在 Spring Boot 中,@Conditional注解及其派生注解为开发者提供了强大的条件化配置能力。这些注解允许我们根据特定条件来决定是否加载某个配置或创建某个 Bean。
- @ConditionalOnClass:当类路径上存在指定类时,条件成立。
- @ConditionalOnMissingClass:当类路径上不存在指定类时,条件成立。
- @ConditionalOnBean:当指定的 Bean 存在时,条件成立。
- @ConditionalOnMissingBean:当指定的 Bean 不存在时,条件成立。
- @ConditionalOnProperty:当指定的属性有指定的值时,条件成立。
- 讲解自定义 Conditional 注解的步骤。
假设我们想要基于某个自定义属性来决定是否加载某个配置,我们可以创建一个自定义的 Condition 实现。
首先创建一个自定义的 Condition 类,实现 Condition 接口并覆盖 matches 方法。在这个方法中,检查自定义属性是否满足条件。然后,在配置类中使用@Conditional(CustomCondition.class)注解来指定这个条件。
三、Spring 在中型项目中的实践心得
1. Mapper 标签及 resultmap 的使用
- 解释 Mapper 标签中 namespace、id、parameterType、resultType 等属性的作用。
在 MyBatis 中,Mapper 标签是用于定义 SQL 语句映射的重要元素。其中,namespace属性用于指定 Mapper 接口的全限定名,它将 Mapper XML 文件与对应的接口关联起来。id属性用于唯一标识 Mapper 中的一个具体 SQL 语句或方法,在调用时通过这个 id 来找到对应的 SQL 语句进行执行。parameterType属性指定传入 SQL 语句的参数类型,可以是基本数据类型、自定义类或集合类型等。resultType属性则定义了 SQL 查询结果的返回类型,同样可以是基本数据类型、自定义类或集合类型等。
- 说明如何使用 resultmap 自定义映射关系。
ResultMap 是 MyBatis 中用于自定义结果映射的重要工具。它允许开发者精确地控制数据库查询结果如何映射到 Java 对象的属性上。例如,当数据库表结构和 Java 对象的属性名称不完全一致时,可以使用 ResultMap 进行自定义映射。假设我们有一个用户表和一个对应的 Java 对象User,如果数据库中的字段名是user_name,而 Java 对象中的属性名是username,我们可以通过 ResultMap 来建立这种映射关系。首先,在 Mapper XML 文件中定义一个 ResultMap:
<resultMap id="UserResultMap" type="User">
<result column="user_name" property="username"/>
</resultMap>
然后,在 SQL 语句中使用这个 ResultMap:
<select id="findUserById" resultMap="UserResultMap">
SELECT * FROM users WHERE id = #{id}
</select>
这样,当执行这个查询时,MyBatis 会根据 ResultMap 的定义将数据库查询结果正确地映射到User对象的username属性上。
2. SpringMVC 的工作原理及流程
- 介绍 SpringMVC 围绕 DispatcherServlet 的工作原理。
SpringMVC 中的DispatcherServlet是整个框架的核心组件,它充当前端控制器的角色,负责接收所有的 HTTP 请求,并协调各个组件对请求进行处理。当一个请求到达服务器时,DispatcherServlet首先会拦截这个请求。然后,它会调用HandlerMapping(处理器映射器)来查找能够处理这个请求的控制器(Controller)。HandlerMapping会根据请求的 URL 等信息找到对应的处理器(通常是一个标注了@Controller注解的类中的方法),并生成一个HandlerExecutionChain对象返回给DispatcherServlet。这个对象包含了处理器和可能的拦截器。接着,DispatcherServlet会使用HandlerAdapter(处理器适配器)来调用处理器方法。HandlerAdapter会将请求和响应对象传递给处理器,处理器执行相应的业务逻辑,并返回一个ModelAndView对象,这个对象包含了视图名和模型数据。最后,DispatcherServlet会根据ModelAndView对象选择合适的ViewResolver(视图解析器)来解析视图名,找到具体的视图(如 JSP、Thymeleaf 模板等)进行渲染,并将结果返回给客户端。
- 阐述 DispatcherServlet 对请求的处理顺序。
当一个请求到达DispatcherServlet时,处理顺序如下:
- 首先,DispatcherServlet拦截请求。
- 接着,调用HandlerMapping根据请求的 URL 查找相应的处理器和可能的拦截器,生成HandlerExecutionChain对象并返回。
- 然后,使用HandlerAdapter调用处理器方法,将请求和响应对象传递给处理器。处理器执行业务逻辑后返回ModelAndView对象。
- 之后,DispatcherServlet将ModelAndView对象传递给ViewResolver进行视图解析,将逻辑视图名转换为具体的视图对象。
- 最后,DispatcherServlet对视图进行渲染,将模型数据填充至视图中,并将结果返回给客户端。
3. Spring 常见概念介绍
- 介绍 Spring 的组成部分,如 Spring Core、Spring Context、Spring AOP 等。
Spring 是一个功能强大的 Java 开发框架,由多个重要的组成部分构成。
- Spring Core:这是 Spring 框架的核心部分,提供了依赖注入(DI)和控制反转(IoC)等基础机制。依赖注入使得开发人员无需手动创建对象并管理它们之间的依赖关系,而是由 Spring 容器负责对象的创建和注入,极大地简化了开发过程。控制反转则将对象的创建和管理的控制权从应用程序代码转移到了 Spring 框架,提高了代码的可维护性和可扩展性。
- Spring Context:提供了一种配置和管理应用程序上下文的方式。它扩展了核心容器,增加了对国际化(i18n)、事件传播、资源加载等功能的支持。通过 Spring Context,可以方便地加载和管理应用程序中的各种资源,如配置文件、数据库连接等。
- Spring AOP:面向切面编程(AOP)是一种编程范式,它允许开发人员将横切关注点(如日志记录、事务管理、安全检查等)从业务逻辑中分离出来。Spring AOP 实现了 AOP 的功能,通过代理模式和字节码增强技术,在不修改业务代码的情况下,将横切关注点织入到业务逻辑中,提高了代码的可维护性和可复用性。
- 讲解 IOC 与 DI 的概念及实现方式。
- IOC(Inversion of Control,控制反转):是一种设计原则,它将对象的创建和依赖关系的管理交给框架(在 Spring 中就是 Spring 容器)来完成,而不是由应用程序代码直接管理。在传统的编程方式中,对象的创建和依赖关系的管理通常由应用程序代码自己负责,这会导致代码的耦合度较高,难以维护和扩展。而在 IOC 的模式下,应用程序代码只需要关注业务逻辑,而不需要关心对象的创建和依赖关系的管理,这使得代码更加简洁、易于理解和维护。
- DI(Dependency Injection,依赖注入):是实现 IOC 的一种方式。它通过将依赖对象注入到需要它们的对象中,实现了对象之间的解耦。在 Spring 中,依赖注入可以通过构造函数注入、setter 方法注入和字段注入等方式实现。例如,通过构造函数注入时,在接受注入的类中定义一个构造函数,并在参数中定义需要注入的元素,Spring 容器在创建对象时会自动调用这个构造函数,并将依赖对象传递给它。通过 setter 方法注入时,在需要注入的类中定义一个 setter 方法,用于接收依赖对象,Spring 容器在创建对象后会调用这个 setter 方法,将依赖对象注入到对象中。通过字段注入时,直接在类的字段上使用注解(如@Autowired),Spring 容器在创建对象时会自动将依赖对象注入到这个字段中。
四、Spring 与策略模式的结合
- 以平台策略模式工厂类为例,展示如何将策略模式与 Spring 结合应用于项目中。
在实际项目中,策略模式可以与 Spring 框架很好地结合,以提高代码的可维护性和可扩展性。例如,在一个电商平台中,可能需要根据不同的用户类型(普通用户、VIP 用户、超级 VIP 用户等)采取不同的折扣策略。我们可以使用策略模式来实现这个功能。
首先,定义一个折扣策略接口DiscountStrategy:
public interface DiscountStrategy {
double calculateDiscount(double price);
}
然后,实现不同的折扣策略类:
@Component
public class NormalUserDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.95;
}
}
@Component
public class VIPUserDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.9;
}
}
@Component
public class SuperVIPUserDiscountStrategy implements DiscountStrategy {
@Override
public double calculateDiscount(double price) {
return price * 0.8;
}
}
接下来,创建一个策略模式工厂类DiscountStrategyFactory:
@Component
public class DiscountStrategyFactory {
@Autowired
private Map<String, DiscountStrategy> strategyMap;
public DiscountStrategy getBy(String strategyName) {
return strategyMap.get(strategyName);
}
}
在业务代码中,可以通过以下方式使用策略模式和 Spring:
@Autowired
private DiscountStrategyFactory discountStrategyFactory;
public double getDiscountedPrice(double originalPrice, String userType) {
DiscountStrategy strategy = discountStrategyFactory.getBy(userType);
if (strategy!= null) {
return strategy.calculateDiscount(originalPrice);
}
return originalPrice;
}
- 介绍 Spring 配置文件在策略模式中的作用。
Spring 配置文件在策略模式中起着重要的作用。它可以帮助我们将不同的策略类注册为 Spring 容器中的 Bean,并且可以通过配置文件来灵活地选择和切换不同的策略。
例如,在上面的电商平台折扣策略的例子中,我们可以在 Spring 配置文件中配置不同的策略类:
<beans>
<bean id="normalUserDiscountStrategy" class="com.example.NormalUserDiscountStrategy"/>
<bean id="vipUserDiscountStrategy" class="com.example.VIPUserDiscountStrategy"/>
<bean id="superVIPUserDiscountStrategy" class="com.example.SuperVIPUserDiscountStrategy"/>
<bean id="discountStrategyFactory" class="com.example.DiscountStrategyFactory"/>
</beans>
通过这种方式,Spring 容器会自动将这些策略类实例化,并注入到DiscountStrategyFactory中。在业务代码中,我们只需要通过DiscountStrategyFactory来获取相应的策略类,而不需要手动创建和管理这些策略类的实例。这样可以大大提高代码的可维护性和可扩展性,并且可以通过修改配置文件来轻松地切换不同的策略。
五、Spring 的国际化实现
- 解释国际化的概念及原理。
国际化(Internationalization),通常简称为 i18n,是指为了适应不同语言、文化和地区的用户,使软件能够方便地进行本地化修改的过程。在 Spring 中,国际化主要通过 MessageSource 和 LocaleResolver 这两个核心组件来实现。MessageSource 负责加载并解析资源文件,根据不同的语言和代码返回相应的消息。LocaleResolver 则用于解析用户的语言偏好,确定要使用哪个语言。
Spring 的国际化实现原理是将应用程序中的文本、标签、消息等资源抽取出来,存放在不同语言的资源文件中。每个资源文件对应一种语言,通常命名为 messages_语言代码.properties 的格式。当应用程序运行时,根据用户的语言偏好,通过 LocaleResolver 确定要使用的语言,然后由 MessageSource 从相应的资源文件中加载并返回对应的消息。这样,应用程序就可以根据用户的语言偏好自动切换语言,实现国际化。
- 阐述如何通过 MessageSource 和 LocaleResolver 实现国际化。
在 Spring 中,MessageSource 和 LocaleResolver 是实现国际化的关键组件。
MessageSource:
ApplicationContext 接口扩展了 MessageSource 接口,提供了国际化功能。Spring 还提供了 HierarchicalMessageSource 接口,可以分层解析消息。这些接口定义的方法包括:
- String getMessage(String code, Object[] args, String default, Locale loc):用于从 MessageSource 获取消息的基本方法。如果在指定的本地没有找到消息,则使用默认消息。通过标准库提供的 MessageFormat 功能,传入的任何参数都会成为替换值。
- String getMessage(String code, Object[] args, Locale loc):与前一种方法基本相同,但有一点不同:不能指定默认信息。如果找不到信息,就会抛出 NoSuchMessageException 异常。
- String getMessage(MessageSourceResolvable resolvable, Locale locale):前面方法中使用的所有属性也都封装在一个名为 MessageSourceResolvable 的类中,你可以使用该方法。
Spring 容器在初始化过程中,会从容器中查找 MessageSource 类型的 Bean。并且该 Bean 的名称必须是 messageSource。如果找到了这样一个 Bean,对前面方法的所有调用都会委托给消息源。如果没有找到消息源,ApplicationContext 会尝试查找包含同名 Bean 的父类。如果找到了,它就会使用该 bean 作为消息源。如果 ApplicationContext 无法找到任何消息源,则会实例化一个空的 DelegatingMessageSource,以便能够接受对上述方法的调用。
例如,可以通过以下方式配置 MessageSource:
@Bean(AbstractApplicationContext.MESSAGE_SOURCE_BEAN_NAME)
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
// 这里设置的是 basename,message 是文件的前缀(不是包)
messageSource.addBasenames("classpath:com/pack/main/databinder/message");
return messageSource;
}
在包 com/pack/main/databinder 下建立多个文件,分别如 message_zh_CN.properties 和 message_en_US.properties。文件内容如下:
message_zh_CN.properties
#姓名必须填写
user.name.empty=\u59D3\u540D\u5FC5\u987B\u586B\u5199
message_en_US.properties
user.name.empty=name is required
调用方式如下:
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class)) {
// Locale.CHINA 或者 Locale.US
System.out.println(context.getMessage("user.name.empty", null, Locale.CHINA));
}
LocaleResolver:
Spring 为我们提供了多种 LocaleResolver 的实现,如 CookieLocaleResolver 和 SessionLocaleResolver。以 CookieLocaleResolver 为例,可以通过设置 cookie 的过期时间,使得在 cookie 有效期内的会话都能保持用户的语言偏好。
<!-- 基于 Cookie 的本地化解析器 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="cookieMaxAge" value="604800"/>
<property name="defaultLocale" value="zh_CN"/>
<property name="cookieName" value="Language"/>
</bean>
在业务代码中,可以通过注入 LocaleResolver 来切换语言。例如:
@Autowired
CookieLocaleResolver resolver;
@RequestMapping("language")
public ModelAndView language(HttpServletRequest request, HttpServletResponse response, String language) {
language = language.toLowerCase();
if (language == null || language.equals("")) {
return new ModelAndView("redirect:/");
} else {
if (language.equals("zh_cn")) {
resolver.setLocale(request, response, Locale.CHINA);
} else if (language.equals("en")) {
resolver.setLocale(request, response, Locale.ENGLISH);
} else {
resolver.setLocale(request, response, Locale.CHINA);
}
}
return new ModelAndView("redirect:/");
}
六、Spring 在微服务架构中的应用
- 介绍微服务架构的特点及优势。
微服务架构具有诸多特点和优势,主要包括以下几点:
- 可扩展性:在增加业务响应能力时,单一架构需要进行整体扩容,而微服务架构仅需要扩容响应能力不足的微服务节点。在增加业务功能时,单一应用架构需要在原先架构的代码基础上做比较大的调整,而微服务架构只需要增加新的微服务节点,并调整与之有关联的微服务节点即可。
- 容错性:在系统发生故障时,单一应用架构需要进行整个系统的修复,涉及到代码的变更和应用的启停,而微服务架构仅仅需要针对有问题的服务进行代码的变更和服务的启停。其他服务可通过重试、熔断等机制实现应用层面的容错。
- 技术选型灵活:微服务架构下,每个微服务节点可以根据完成需求功能的不同,自由选择非常适合的技术栈,即使对单一的微服务节点进行重构,成本也非常低。
- 开发运维效率更高:每个微服务节点都是一个单一进程,都专注于单一功能,并通过定义良好的接口清晰表述服务边界。由于体积小、复杂度低,每个微服务可由一个小规模团队或者个人完全掌控,易于保持高可维护性和开发效率。
- 讲解 Spring Cloud 在微服务中的技术选型和主流组件。
Spring Cloud 作为强大的微服务架构开发工具,提供了一系列组件和工具来简化微服务架构的开发、部署和管理。
- 服务注册与发现:
-
- Eureka:Netflix 开源的服务注册与发现工具,通过服务的注册和查找实现服务的自动化。适合需要动态服务发现的系统。
-
- Consul:支持多种场景的服务发现和配置,具有健康检查、键值存储等附加功能。
-
- Zookeeper:适合需要高可用性和 CAP 理论中 CP 特性的分布式系统。
- 分布式配置管理:
-
- Spring Cloud Config:提供集中化的外部配置管理,支持 Git、SVN 等版本控制系统,轻松应对不同环境的配置管理。
- 客户端负载均衡:
-
- Ribbon:提供基于 Http 和 Tcp 的负载均衡功能,支持多种负载均衡策略(如轮询、随机等)并可以与 Eureka 集成。
-
- Spring Cloud LoadBalancer:在 Spring Cloud Hoxton 版引入,更现代的替代品,与 Spring 对于响应式和阻塞式 Web 客户端的整体战略相结合。
- 断路器:
-
- Hystrix:原为 Netflix 的开源项目,提供了弹性和控制延迟故障的能力。适用于需要监控和故障恢复的系统。
-
- Resilience4j:作为 Hystrix 的继任者,以其更轻量和现代化架构,逐渐取代 Hystrix 在 Spring 生态下的使用。
- API 网关:
-
- Spring Cloud Gateway:现代化设计的 API 网关,替代 Zuul 1,以其非阻塞和高度扩展性支持复杂的路由与过滤规则。
-
- Zuul:最初也是 Netflix 提供的解决方案,适合简单的路由和过滤需求。
- 分布式追踪:
-
- Sleuth 和 Zipkin:提供对分布式服务调用的跟踪和可视化,希望深入监控单个请求的调用链分析。
-
- Jaeger:在分布式追踪和性能监控领域,提供了一个全面系统化的解决方案。
七、Spring 在中型项目中的优势
- 列举 Spring 在中型项目中的优势,如支持测试驱动开发、插件化结构等。
Spring 在中型项目中具有诸多优势。首先,它支持测试驱动开发,这使得开发人员能够在编写产品代码之前先编写测试用例,确保代码的正确性和可靠性。正如写作素材中提到的,测试驱动开发可以有效提高代码质量,让程序开发人员开发出更高品质、经过完整测试的程序。同时,Spring 还具有类似 USB 接口的插件化结构,如 Spring Boot 的插件化开发功能,极大地提升了系统的扩展性和灵活性。插件化开发允许开发人员将应用程序的不同功能模块打包为独立的插件,可以动态地加载和卸载这些插件,实现了真正的动态扩展和无痛升级。此外,Spring 的插件化结构还可以实现服务模块之间的解耦,提升系统的可定制化、个性化程度,方便第三方接入,并且增强了系统的扩展性和开放性。
- 说明何时适合使用 Spring 框架。
一般来说,中型项目比较适合使用 Spring 框架。在中型项目中,Spring 框架可以发挥其强大的功能和优势,简化开发过程,提高代码的可维护性和可扩展性。Spring 框架的插件化结构和支持测试驱动开发等特性,使得开发人员能够更加高效地开发和维护中型项目。此外,Spring 框架还具有相对容易升级、事务管理服务(基于 AOP)等优点,能够满足中型项目的复杂需求。而对于小型项目,可能使用 Spring 框架会显得有些繁琐;对于大型项目,虽然也可以使用 Spring 框架,但可能需要结合其他更强大的框架来满足复杂的业务需求。总之,中型项目是 Spring 框架发挥优势的理想场景。
八、Spring 在中型项目中的应用案例
1. Spring Cloud 在中小型项目中的应用
- 介绍 Spring Cloud 的服务发现、断路器、智能路由等组件。
Spring Cloud 是一个基于 Spring Boot 的微服务架构开发工具集,它提供了一系列组件来简化微服务架构的开发、部署和管理。其中,服务发现、断路器和智能路由是其核心组件之一。
服务发现组件如 Eureka、Consul 等,用于管理微服务的注册和发现。当微服务启动时,它会向服务发现组件注册自己的服务地址和端口等信息。其他微服务可以通过服务发现组件获取到所需服务的地址信息,从而实现服务之间的通信。服务发现组件使得微服务架构中的服务可以动态地加入和退出,提高了系统的可扩展性和灵活性。
断路器组件如 Hystrix、Resilience4j 等,用于处理微服务架构中的故障。当一个微服务出现故障时,断路器可以快速地切断对该服务的调用,避免故障扩散到其他服务。同时,断路器还可以提供降级策略,当服务不可用时,返回一个预设的默认值或者执行一个备用的逻辑,提高了系统的可靠性和稳定性。
智能路由组件如 Zuul、Spring Cloud Gateway 等,用于实现微服务架构中的请求路由和过滤。智能路由组件可以根据请求的 URL、HTTP 方法、请求头信息等条件,将请求转发到不同的微服务上。同时,智能路由组件还可以实现一些通用的功能,如身份验证、访问控制、日志记录等,提高了系统的安全性和可维护性。
- 讲解如何搭建 eureka-server、config-server 和服务提供者服务。
搭建 eureka-server:
- 修改 build.gradle 文件(如果是 Maven 项目请对应的修改 pom.xml),添加 Spring Cloud Eureka Server 的依赖。
- 修改 application.yml,配置 Eureka Server 的相关参数,如端口号、服务注册地址等。
- 修改程序的主类,添加@EnableEurekaServer注解,然后运行 main 方法。
搭建 config-server:
- 修改 build.gradle 文件,添加 Spring Cloud Config Server 的依赖。
- 修改 application.yml 文件,配置 Config Server 的相关参数,如端口号、配置文件路径等。
- 修改启动类,添加相应的注解,因为要注册到 eureka-server 上,所以需要@EnableEurekaClient这个注解。
搭建服务提供者服务:
- 修改 build.gradle 文件,添加服务提供者所需的依赖,如 Spring Web、Spring Data JPA 等。
- 编写服务提供者的代码,提供相应的接口,如获取单个用户的信息和获取一个用户列表。
- 配置 application.yml 和 bootstrap.yml 文件,配置服务提供者的相关参数,如端口号、服务名称、Eureka 地址等。
2. 15 款 Spring 开源项目脚手架推荐
- 推荐 15 款优质开源的 Spring Boot & Spring Cloud 项目脚手架。
以下是 15 款优质开源的 Spring Boot & Spring Cloud 项目脚手架:
- 微人事:一个前后端分离的人力资源管理系统,项目采用 Spring Boot + Vue 开发,加入了常见的企业级应用技术点,如 Redis、RabbitMQ 等。
- spring-boot-pay:支付服务项目,支持支付宝、微信、银联等支付方式。
- springboot-plus:一个基于 Spring Boot 2 的管理后台系统,包含用户管理、组织机构管理、角色管理等功能,使用简单,可完成中型、大型系统开发。
- Spring-boot-seckill:一个基于 Spring Boot 2 的秒杀系统,包含用户管理、商品管理、订单管理等功能。
- V 部落:一个多用户博客管理平台,采用 Vue + Spring Boot 开发。
- Cloud-Platform:国内首个基于 Spring Cloud 微服务化开发平台,具有统一授权、认证后台管理系统,包含用户管理、资源权限管理、网关 API 管理等多个模块。
- litemall:一个小商场系统,采用 Spring Boot 后端 + Vue 管理员前端 + 微信小程序用户前端 + Vue 用户移动端的架构。
- jeeSpringCloud:基于 Spring Boot 2.0 的后台权限管理系统,界面简洁美观,敏捷开发系统架构,包含定时任务调度、服务器监控、平台监控等功能。
- 美人鱼:一个系列项目,目标是示范前后端分离模式下的项目组织方式,前端提供浏览器、移动端、Electron 实现,后端提供 Spring Boot、Spring Cloud 实现。
- bootshiro:基于 springboot2 + shiro + jwt 的真正 rest api 资源无状态认证权限管理框架,开发人员无需关注权限问题,后端开发完 api,前端页面配置即可。
- open-capacity-platform:简称 ocp,是基于 Spring Cloud 的企业级微服务框架,兼容 spring cloud netflix 和 spring cloud alibaba,优化 Spring Security 内部实现,实现 API 调用的统一出口和权限认证授权中心。
- 悟空 CRM:悟空软件长期为企业提供企业管理软件(CRM/HRM/OA/ERP 等)的研发、实施、营销、咨询、培训、服务于一体的信息化服务。
- pig:基于 Spring Cloud 2020、Spring Boot 2.5、OAuth2 的 RBAC 权限管理系统。
- 介绍其中几个项目的特点和技术栈。
以微人事为例,其特点是前后端分离,采用 Spring Boot + Vue 开发,加入了 Redis、RabbitMQ 等技术点。技术栈包括:
- 前端:Vue、PrimeNG、Bootstrap、Echarts、ngx-echarts、ckeditor5-angular。
- 后端:Spring Boot、Spring Cloud、Spring Data JPA、MyBatis、Spring、Spring MVC。
以 springboot-plus 为例,其特点是使用简单,可以轻易完成中型、大型系统开发。技术栈包括:
- 系统基于 Spring Boot 2.1 技术,前端采用了 Layui 2.4。
- 数据库以 MySQL/Oracle/Postgres/SQLServer 为实例,理论上是跨数据库平台。
以 Cloud-Platform 为例,其特点是国内首个基于 Spring Cloud 微服务化开发平台,具有统一授权、认证后台管理系统。技术栈包括:
- 核心技术采用 Spring Boot 2.1.2 以及 Spring Cloud (Greenwich.RELEASE) 相关核心组件,采用 Nacos 注册和配置中心,集成流量卫兵 Sentinel,前端采用 vue-element-admin 组件,Elastic Search 自行集成。
3. Spring Boot 企业级真实应用案例
- 以企业级项目为例,展示 Spring Boot 的实战应用。
以一个企业级商城项目为例,展示 Spring Boot 的实战应用。该项目包含一个内容展示系统和一个后台管理系统,其中功能模块包括登录认证模块、管理员模块、商品发布和管理模块、分类管理模块、搜索模块、订单管理模块、会员管理模块等。
在项目开发过程中,使用 Spring Boot 分别实现各个独立的功能点,比如图片上传功能、分页功能、登录功能、验证码功能等,并整合多个独立的基础功能到一个完整的功能模块中,最终完成各个功能模块的功能和交互,开发出一个完整的商城系统。
- 说明本书的特色和读者收获。
本书的特色:
- Spring Boot 相关技术栈源码设计和内部原理解析,知其然,知其所以然。
- 大型电商全流程开发实践,叩开大企之门的真理,知易行难,实践出真知。
- 全书知识点实用,案例丰富,细节拉满,源码完备,见微知著,通一而晓百。
读者收获:
- Spring Boot 技术栈的基础使用和开发技巧。
- Spring Boot 的进阶知识,自动配置特性的源码解读。
- Spring Boot 项目的实战开发。
- 为在校学生的毕业设计提供思路。
- Thymeleaf 模板引擎的整合及运用。
- AdminLTE3、Bootstrap4、SweetAlert、JqGrid、JQuery 等前端框架组件及控件的使用。
- Spring Boot 企业级商城项目的全流程开发实践。
- 大型技术项目的开发、设计和统筹。
相关文章:
《参与中型项目,领略 Spring 魅力》
一、Spring 在中型项目中的魅力展现 Spring 框架以其强大的功能和灵活性,在中型项目中发挥着重要作用。它不仅简化了开发过程,还提高了代码的可维护性和可扩展性。 Spring 在中型项目中魅力十足,其优势主要体现在以下几个方面。 首先&#…...
计算机网络-GRE(通用路由封装协议)简介
昨天我们学习了VPN的基本概念,虚拟专用网络在当前企业总部与分支间广泛使用。常用的划分方法为基于协议层次有GRE VPN、IPSec VPN、L2TP VPN、PPTP VPN、SSL VPN等。其实我有考虑该怎么讲,因为在IP阶段好像虚拟专用网络讲得不深,在IE的阶段会…...
开源电话机器人产品的优点是什么?
开源电话机器人产品的优点是什么? 作者:开源呼叫中心系统 FreeIPCC,Github地址:https://github.com/lihaiya/freeipcc 开源电话机器人产品作为人工智能技术的一种应用,近年来在电销、客户服务等多个领域展现出了显著的…...
Spring Boot 集成 Knife4j 的 Swagger 文档
在开发微服务应用时,API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具,可以帮助我们自动生成 RESTful API 的文档,并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j …...
极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【一】
GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料: 极狐GitLab 官网极狐…...
C# 在Word文档模板中,按照占位符插入文字或图片
1,引入包:DocX 2,代码如下 public class CC{public static void Ma22in(){// 示例:加载现有模板并替换占位符string templatePath "报告模板.docx"; // 模板文件路径string outputPath "Output.docx"; // 输出文…...
在使用PCA算法进行数据压缩降维时,如何确定最佳维度是一个关键问题?
一、PCA算法的基本原理 PCA算法的核心思想是通过正交变换,将一组可能相关的变量转换成一组线性不相关的变量,称为主成分。这组主成分能够以最小的信息损失来尽可能多地保留原始数据集的变异性。具体来说,PCA算法包括以下几个步骤:…...
深度学习3
五、自动微分 1、基础概念 模块 autograd 负责自动计算张量操作的梯度,具有自动求导功能;autograd 创建一个动态计算图来跟踪张量的操作,每个张量是计算图中的一个节点,节点之间的操作构成图的边。 属性 requires_grad 决定…...
Qt5.14.2的安装与环境变量及一些依赖库的配置
目录 1.Qt5.14.2安装 2.Qt环境变量及一些依赖库的配置 1.Qt5.14.2安装 QT从入门到入土(一)——Qt5.14.2安装教程和VS2019环境配置 - 唯有自己强大 - 博客园 2.Qt环境变量及一些依赖库的配置 假设QT安装目录为: D:\Qt\Qt5.14.2 将目录: D:\Qt\Qt5.14.…...
PYNQ 框架 - 时钟系统 + pl_clk 时钟输出不准确问题
目录 1. 简介 2. PS 时钟计算 2.1 计算框架 2.2 KV260 的参考时钟 2.3 PL_CLK 设置 3. 测试 3.1 Block design 3.2 引脚绑定 3.3 使用 AD2 测量 3.4 调整分频 4. PYNQ 时钟驱动 4.1 源码解析 4.2 查看 PL_CLK 4.3 配置 PL_CLK 5. 总结 1. 简介 ZYNQ MPSoC 具有…...
CDAF / PDAF 原理 | PDAF、CDAF 和 LAAF 对比 | 图像清晰度评价指标
注:本文为 “CDAF / PDAF 原理 | PDAF、CDAF 和 LAAF 对比 | 图像清晰度评价指标” 几篇相关文章合辑。 文章中部分超链接、图片异常受引用之前的原文所限。 相机自动对焦原理 TriumphRay 于 2020-01-16 18:59:41 发布 凸透镜成像原理 这一部分大家中学应该就学过…...
类和对象--中--初始化列表(重要)、隐式类型转化(理解)、最后两个默认成员函数
1.初始化列表 1.1作用: 通过特定的值,来初始化对象。 1.2定义: 初始化列表,就相当于定义对象(开空间)。不管写不写初始化列表,每个成员变量都会走一遍初始化列表(开出对应的空间…...
uni-app运行 安卓模拟器 MuMu模拟器
最近公司开发移动端系统,使用真机时每次调试的时候换来换去的麻烦,所以使用模拟器来调试方便。记录一下安装和连接的过程 一、安装MuMu模拟器 百度搜索MuMu模拟器并打开官网或者点这里MuMu模拟器官网 点击下载模拟器 安装模拟器,如果系统…...
java 打印对象所有属性的值 循环
在Java中,如果你想要打印一个对象的所有属性值,可以使用反射(Reflection)来获取对象的所有字段,并循环遍历这些字段以打印它们的值。以下是一个示例代码,展示了如何实现这一点: 示例类 假设我…...
k8s认证、授权
在 Kubernetes 中,kubectl auth can-i 命令用于检查当前用户或指定的 ServiceAccount 是否有权限执行特定的操作: kubectl auth can-i create deployment --as system:serviceaccount:default:dev-sa这个命令的作用是检查名为 dev-sa 的 ServiceAccount…...
基于spring boot的纺织品企业财务管理系统论文
摘 要 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对纺织品企业财务信息管理的提升&…...
@RequestBody和前端的关系以及,如何在前后端之间传递数据?
RequestBody 注解在 Spring MVC 中用于将 HTTP 请求体中的数据绑定到控制器方法的参数上。为了更好地理解 RequestBody 和前端之间的关系,我们可以从以下几个方面进行探讨: 1. 请求体的格式 前端发送的请求体通常是一个 JSON 字符串,也可以…...
详解登录MySQL时出现SSL connection error: unknown error number错误
目录 登录MySQL时出错SSL connection error: unknown error number 出错原因 使用MySQL自带的工具登录MySQL 登陆之后,使用如下命令进行查看 解决方法 找到MySQL8安装目录下的my.ini配置文件 记事本打开my.ini文件,然后按下图所示添加配置 此时再…...
【大数据学习 | Spark-Core】Spark的改变分区的算子
当分区由多变少时,不需要shuffle,也就是父RDD与子RDD之间是窄依赖。 当分区由少变多时,是需要shuffle的。 但极端情况下(1000个分区变成1个分区),这时如果将shuffle设置为false,父子RDD是窄依赖关系&…...
Spring Boot Web应用开发:测试
在Spring Boot中,测试是开发过程的一个重要部分,它确保你的应用按预期工作,并且可以帮助你在早期发现和修复问题。Spring Boot提供了多种便捷的测试工具,使得编写和运行测试案例变得简单。 Spring Boot测试简介 Spring Boot支持…...
服务器数据恢复—光纤存储FC硬盘数据恢复案例
服务器存储数据恢复环境: 某品牌光纤存储上共有16块FC硬盘。存储上的卷映射到Linux操作系统上。Linux操作系统上运行Oracle数据库。 服务器存储故障&检测: 存储上2块硬盘故障灯亮起,存储映射到linux操作系统上的卷挂载不上,业…...
Android Binder技术概览
Android中的Binder是一种基于远程过程调用(Remote Procedure Call, RPC)的轻量级通信机制,核心用于 Android 系统中的进程间通信(Inter-Process Communication, IPC)。Binder 是 Android 系统中不可或缺的一部分&#…...
09 —— Webpack搭建开发环境
搭建开发环境 —— 使用webpack-dev-server 启动Web服务,自动检测代码变化,有变化后会自动重新打包,热更新到网页(代码变化后,直接替换变化的代码,自动更新网页,不用手动刷新网页) …...
深度学习模型:卷积神经网络(CNN)
一、前言 CNN 的发展历程可以追溯到 20 世纪 80 年代和 90 年代。受生物视觉系统的启发,研究人员开始探索如何构建专门用于处理图像数据的神经网络。早期的一些研究奠定了基础,例如 Fukushima 提出的 Neocognitron 模型。 随着时间的推移,到…...
Flask 自定义路由转换器
步骤 创建自定义转换器类 继承 werkzeug.routing.BaseConverter。实现 to_python 和(可选)to_url 方法。 将转换器注册到 Flask 应用 在路由中使用转换器 示例 创建转换器 假设需要自定义一个转换器 FourDigitYearConverter,用于匹配四位年…...
【淘汰9成NLP面试者的高频面题】LSTM中的tanh和sigmoid分别用在什么地方?为什么?
博客主页: [青松] 本文专栏: NLP 大模型百面百过 【淘汰9成NLP面试者的高频面题】LSTM中的tanh和sigmoid分别用在什么地方?为什么? 重要性:★★★ 💯 本题主要考察面试者对以下问题的理解: ① 数据特征和模…...
gocv调用opencv添加中文乱码的解决方案
前言 相信很多做视觉的同学在使用opencv给图片添加中文文字的时候会出现这样的乱码显示: 而实际上你期望的是“告警时间:2011-11-11 11:11:11 告警类型:脱岗检测告警 Area:XXXXX Camera:Camera001-001”这样的显示内容,那么这篇文章我将用很简单的方法来解决乱码问题,只需…...
org.apache.log4j的日志记录级别和基础使用Demo
org.apache.log4j的日志记录级别和基础使用Demo,本次案例展示,使用是的maven项目,搭建的一个简单的爬虫案例。里面采用了大家熟悉的日志记录插件,log4j。来自apache公司的开源插件。 package com.qian.test;import org.apache.log…...
IC数字后端实现之大厂IC笔试真题(经典时序计算和时序分析题)
今天小编给大家分享下每年IC秋招春招必考题目——静态时序分析时序分析题。 数字IC后端笔试面试题库 | 经典时序Timing计算题 时序分析题1: 给定如下图所示的timing report,请回答一下几个问题。 1)这是一条setup还是hold的timing report?…...
java centos 离线使用sherpa-onnx文字转语音TTS
sherpa-onnx: https://github.com/k2-fsa/sherpa-onnx.git 文档链接;Java API — sherpa 1.3 文档 1. 项目基础介绍和主要编程语言 sherpa-onnx 是一个基于下一代 Kaldi 和 onnxruntime 的开源项目,专注于语音识别、文本转语音、说话人识别和语音活动检测(VAD)等功能。该项…...
最火的服务器托管/名词解释seo
2.搭建双主双从 编号 角色 Ip地址 机器名 1 Master1 192.168.119.131 Hadoop2 2 Slave1 192.168.119.132 Hadoop3 3 Master2 192.168.119.133 Hadoop1 4 Slave2 192.168.119.134 Hadoop4 2.1修改配置文件 修改四台服务器的/etc/my.cnf文件 ①Master1 [mysqld] server-id1 #…...
网站建设作者墙这个模板/seo内容优化是什么意思
Linux hosts.allow与hosts.deny文件设置 转自: http://purpen.iteye.com/blog/1135342 redhat as4常用应用之hosts.allow和hosts.deny 一、概述 这两个文件是tcpd服务器的配置文件,tcpd服务器可以控制外部IP对本机服务的访问。这两个配置文件的格式如下&…...
网站内容维护/短信营销
Description Input 有若干行,每行三个数字 X;Y;Z 代表一组数据,表示立方体的长宽高加 1 Output 第 i 行数据输出Case#i: 第i组数据的答案 Sample Input 2 1 22 2 2Sample Output Case #1: 4Case #2: 15HINT x,y,z<1000 Source 郑州培训D3考试…...
企业所得税2020最新/深圳seo优化电话
直接取value即可。 refurl:http://bbs.csdn.net/topics/300110528...
做俄罗斯外贸的网站/打开app下载
前段时间,栈长发布了一篇关于Java 8 Optional map的实用文章,留言区就有的人说 Java 8 的语法糖不方便调试,还要视情况使用。留言区也有人说 IntelliJ IDEA 早已支持 Java 8 Stream 调试,因为我平时也很少调试,那么我就…...
wordpress 高亮代码/seo指的是什么意思
引言互联网时代,信息传输的基础媒介是比特流,即承载着各种有效信息的01串。换句话说,我们在手机上或者电脑上看到的各类媒体信息,例如文字信息、图片信息亦或是视频信息,其根源上都是一些由二进制的0和1组成的比特流。…...