分布式微服务系统架构第142集:全栈开发

加群联系作者vx:xiaoda0423

仓库地址:https://webvueblog.github.io/JavaPlusDoc/

https://1024bat.cn/

https://github.com/webVueBlog/fastapi_plus

https://webvueblog.github.io/JavaPlusDoc/

go 复制代码
/**
 * 本地启动解决跨域问题
 *  打包发布请注释该类,可能会造成一定的影响,解决本地启动跨域问题
 */
go 复制代码
@Override
public  void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
        throws ServletException, IOException {
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    //设置响应内容类型
    response.setContentType("application/json; charset=utf-8");
    //设置响应字符编码
    response.setCharacterEncoding("UTF-8");
    //设置Access-Control-Max-Age,表示在3600秒内不需要再次发送预检请求
    response.setHeader("Access-Control-Max-Age", "3600");
    //设置允许的HTTP请求方法
    response.setHeader("Access-Control-Allow-Methods", "POST, GET,PUT, OPTIONS, DELETE");
    //设置允许的跨域请求来源
    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    //设置是否允许发送Cookie
    response.setHeader("Access-Control-Allow-Credentials", "true");
    //设置允许的请求头
    response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
    //继续执行过滤器链
    filterChain.doFilter(request, response);
}
go 复制代码
用户提交表单会携带验证码相关参数,产品应用在相关接口处将该参数传给 集成jar包相关接口做二次校验,以确保该次验证是正确有效的。

引入相关组件,调用初始化函数,通过配置的一些参数信息。将行为验证码渲染出来。
go 复制代码
<dependency>
    <groupId>com.anji-plus</groupId>
    <artifactId>spring-boot-starter-captcha</artifactId>
    <version>1.3.0</version>
</dependency>
go 复制代码
缓存实现
go 复制代码
public interface CaptchaCacheService {

    void set(String key, String value, long expiresInSeconds);

    boolean exists(String key);

    void delete(String key);

    String get(String key);

    /**
     * 缓存类型-local/redis/memcache/..
     * 通过java SPI机制,接入方可自定义实现类
     * @return
     */
    String type();
}
go 复制代码
二次校验接口
go 复制代码
请求方式
go 复制代码
请求参数
go 复制代码
响应参数
go 复制代码
异常代号
go 复制代码
登录为例,用户在提交表单到产品应用后台,会携带一个验证码相关的参数。产品应用会在登录接口login中将该参数传给集成jar包中相关接口做二次校验。
接口地址:https://****/captcha/verify
go 复制代码
HTTP POST, 接口仅支持POST请求, 且仅接受 application/json 编码的参数
参数 类型 必填 备注
captchaVerification String Y 验证数据,aes加密,数据在前端success函数回调参数中获取
参数 类型 必填 备注
repCode String Y 异常代号
success Boolean Y 成功或者失败
error Boolean Y 接口报错
repMsg String Y 错误信息
error 说明
0000 无异常,代表成功
9999 服务器内部异常
0011 参数不能为空
6110 验证码已失效,请重新获取
6111 验证失败
6112 获取验证码失败,请联系管理员
go 复制代码
引入前端vue组件, npm install axios    crypto-js   -S

CryptoJS是一个JavaScript的加解密的工具包

go 复制代码
<template>
    <Verify
       @success="'success'" //验证成功的回调函数
       :mode="'fixed'"     //调用的模式
       :captchaType="'blockPuzzle'"    //调用的类型 点选或者滑动   
       :imgSize="{ width: '330px', height: '155px' }"//图片的大小对象
    ></Verify
</template>

<script>
//引入组件
import Verify from "./../../components/verifition/Verify";
export default {
    name: 'app',
    components: {
       Verify
    }
    methods:{
       success(params){
       // params 返回的二次验证参数
       }
    }
}
</script>

事件

参数 说明
success 验证码匹配成功后的回调函数
error 验证码匹配失败后的回调函数
ready 验证码初始化成功的回调函数
go 复制代码
验证码参数
参数 说明
captchaType 1)滑动拼图 blockPuzzle 2)文字点选 clickWord
mode 验证码的显示方式,弹出式pop,固定fixed,默认是:mode : 'pop'
vSpace 验证码图片和移动条容器的间隔,默认单位是px。如:间隔为5px,设置vSpace:5
explain 滑动条内的提示,不设置默认是:'向右滑动完成验证'
imgSize 其中包含了width、height两个参数,分别代表图片的宽度和高度,支持百分比方式设置 如:{width:'100%',height:'200px'}
blockSize 其中包含了width、height两个参数,分别代表拼图块的宽度和高度,如:{width:'40px',height:'40px'}
barSize 其中包含了width、height两个参数,分别代表滑动条的宽度和高度,支持百分比方式设置,如:{width:'100%',height:'40px'}
go 复制代码
{
    "captchaType": ""  //验证码类型
}

在CentOS 4.x开始用 fontconfig 来安装字体库,所以输入以下命令即可:

go 复制代码
sudo yum -y install fontconfig

这段代码是一个 Spring Bean 的定义,涉及到一个名为 AjCaptchaCacheService 的服务的初始化过程。具体是根据 AjCaptchaProperties 配置来创建一个 CaptchaCacheService 实例。这里面包含了对不同缓存类型的支持(比如 Redis 本地缓存等),并且在特定条件下做了额外的配置(例如设置 Redis 模板)。以下是对代码的逐行解析:

1. @Bean(name = "AjCaptchaCacheService")

  • 作用 :这个注解表示该方法是一个 Spring Bean,AjCaptchaCacheService 是这个 Bean 的名字。Spring 会将这个方法的返回值注册为一个 Bean,并且在上下文中可以通过这个名字来获取该 Bean。

2. @Primary

  • 作用 :这个注解标记了该 Bean 为优先使用的 Bean。如果 Spring 容器中有多个相同类型的 Bean 时,@Primary 表示该 Bean 会作为默认的选择进行注入,避免需要手动指定 @Qualifier

3. public CaptchaCacheService captchaCacheService(AjCaptchaProperties config)

  • 方法签名 :这个方法定义了一个名为 captchaCacheService 的 Bean,返回类型是 CaptchaCacheService,并且接收一个 AjCaptchaProperties 类型的参数 config,它是从 Spring 容器中注入的配置对象。AjCaptchaProperties 可能包含了与验证码相关的配置,比如缓存类型、过期时间等。

4. CaptchaCacheService ret = CaptchaServiceFactory.getCache(config.getCacheType().name());

  • 功能 :这一行代码通过 CaptchaServiceFactory 工厂类的 getCache 方法,根据 config.getCacheType().name() 获取对应的缓存服务类型,并返回一个 CaptchaCacheService 实例。config.getCacheType().name() 的值(例如 "REDIS" 或 "LOCAL")可能指定了缓存的类型。

    • 如果 config.getCacheType() 为 Redis 缓存类型,则 getCache() 会返回一个 CaptchaCacheServiceRedisImpl 类型的实例。

    • 如果是本地缓存或其他缓存类型,则返回不同的实现类。

5. if(ret instanceof CaptchaCacheServiceRedisImpl){

  • 功能 :如果返回的 CaptchaCacheServiceCaptchaCacheServiceRedisImpl 类型的实例(即是 Redis 缓存实现),则进入这个 if 分支进行进一步配置。

6. ((CaptchaCacheServiceRedisImpl) ret).setStringRedisTemplate(redisTemplate);

  • 功能 :这行代码是将 StringRedisTemplate 设置到 CaptchaCacheServiceRedisImpl 实例中。StringRedisTemplate 是 Redis 操作的一个 Spring 模板类,它提供了对 Redis 字符串数据的封装,简化了 Redis 操作。

    • redisTemplate 可能是一个已经注入到当前类中的 Redis 模板实例,这里通过 setStringRedisTemplate 方法将其设置到 CaptchaCacheServiceRedisImpl 实例中,使得该实例能够使用 StringRedisTemplate 进行 Redis 操作。

7. return ret;

  • 功能 :返回创建好的 CaptchaCacheService 实例(ret)。这个实例会被 Spring 容器管理,并且可以在需要使用 CaptchaCacheService 的地方注入和使用。

代码总结

该方法根据 AjCaptchaProperties 配置动态选择一个缓存类型,并根据缓存类型初始化 CaptchaCacheService 实例。若缓存类型为 Redis,则进一步注入 StringRedisTemplate 以支持 Redis 操作。最终返回的 CaptchaCacheService 实例会作为 Bean 被 Spring 容器管理和注入使用。

适用场景

这种方式适用于需要根据配置来灵活选择缓存类型的场景。例如,当缓存方式可以在 Redis 和本地缓存之间切换时,采用这种方法可以避免在不同环境中修改大量的代码,便于配置化管理。

@Bean(name = "AjCaptchaCacheService") 是 Spring 中用来定义 Bean 的一种方式,name 属性的作用和为什么这么写可以从以下几个方面来理解:

1. name 属性的作用

在 Spring 中,@Bean 注解用来定义一个 Bean,name 属性则指定该 Bean 的名称。默认情况下,如果没有指定 name,Spring 会根据方法名(即 captchaCacheService)作为 Bean 的名称。

示例:

go 复制代码
@Bean(name = "AjCaptchaCacheService")
public CaptchaCacheService captchaCacheService(AjCaptchaProperties config) {
    //...
}

这里,@Bean(name = "AjCaptchaCacheService") 表示将该 Bean 注册到 Spring 容器时,使用 AjCaptchaCacheService 作为其名称。也就是说,在 Spring 容器中,这个 CaptchaCacheService 的实例将被引用为 AjCaptchaCacheService

默认名称与自定义名称的区别:
  • 如果没有指定 name,Spring 会将 Bean 的名称默认设置为方法名称(即 captchaCacheService)。

  • 如果指定了 name,则这个 Bean 会以指定的名称(即 AjCaptchaCacheService)注册到容器中。

2. 为什么这么写

在这个上下文中,给 Bean 指定一个明确的名称有几个目的:

  • 避免命名冲突 :假设 Spring 容器中有多个 CaptchaCacheService 类型的 Bean,如果不指定名称,Spring 会使用方法名称(captchaCacheService)作为默认的名称。如果容器中已经存在一个名为 captchaCacheService 的 Bean,那么 Spring 就会发生冲突,导致注入失败。通过指定一个自定义名称(例如 AjCaptchaCacheService),可以确保唯一性。

  • 方便引用 :指定名称后,可以在其他地方通过名称来引用该 Bean。例如,如果你需要通过 @Autowired 注入该 Bean,可以明确指定使用 AjCaptchaCacheService,避免因为默认名称造成的混淆。

  • 明确的命名意图AjCaptchaCacheService 作为 Bean 名称清楚表达了该 Bean 与 AjCaptchaProperties 和验证码相关,具备较好的可读性与语义性。

3. 相关注解和配置

@Primary 也在代码中出现,说明这个 Bean 是默认注入的优先选择。当有多个同类型的 Bean 时,Spring 会优先注入被标记为 @Primary 的 Bean。name@Primary 结合使用,有助于明确在多个同类型 Bean 存在时,注入哪个 Bean。


总结

  • name 属性用来指定 Spring 容器中注册的 Bean 名称,避免命名冲突,增强可读性和可维护性。

  • 如果不指定,Spring 默认使用方法名作为 Bean 名称。

  • 在这个代码中,AjCaptchaCacheService 明确指定了该 Bean 的名称,避免了潜在的冲突,并且使代码的意图更加明确。

在 Java 项目中,META-INF 文件夹是一个非常特殊的目录,通常存在于项目的 resources 文件夹中,并且在项目打包成 .jar.war 等格式时,会被保留在其中。META-INF 目录的主要作用是存放关于 JAR 文件或者类路径下的元数据信息。它的内容通常与 Java 类加载、服务发现、JAR 描述、加密算法等方面有关。

META-INF 目录的常见用途和内容

  1. META-INF/MANIFEST.MF
  • Manifest-Version 表示 manifest 文件的版本;

  • Class-Path 用来指定该 JAR 依赖的外部类库;

  • Main-Class 表示执行该 JAR 文件时的主类。

  • 作用 :这是最常见的文件,它包含了关于 JAR 文件的元数据。MANIFEST.MF 文件包含了 JAR 文件的版本、类路径、主类、作者信息等。

  • 示例

    go 复制代码
    Manifest-Version: 1.0
    Class-Path: lib/some-library.jar
    Main-Class: com.example.Main
  • 其中:

  • 服务提供者配置文件(META-INF/services/

    • 作用 :Java 提供了一种服务加载机制 ,这让不同的组件可以通过接口约定和插件机制来进行解耦。通过在 META-INF/services/ 目录下定义一个以接口全限定类名命名的文件,并列出服务实现类的全限定名,Java 程序可以在运行时动态加载实现类。

    • 示例

      假设有一个接口 com.example.PaymentProcessor,在 META-INF/services/com.example.PaymentProcessor 文件中可以列出实现该接口的具体类名:

      go 复制代码
      com.example.impl.PayPalProcessor
      com.example.impl.StripeProcessor
    • 这种机制使得 Java 可以根据接口找到不同的实现类,常见的应用场景包括 SPI(Service Provider Interface)和一些依赖注入框架。

  • **META-INF/spring.factories**(在 Spring 框架中)

    • 作用 :Spring 框架使用这个文件来进行自动化配置。spring.factories 文件允许将配置文件、Bean 定义、自动装配逻辑与应用的主要代码解耦,自动加载相关配置和组件。

    • 示例

      go 复制代码
      org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
      org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
  • **META-INF/beans.xml**(在 Java EE 中)

    • 作用beans.xml 是一个配置文件,它定义了一个 Java EE 应用中包含的 CDI(Context and Dependency Injection)Bean。它的作用是启用 CDI 容器,控制和管理类的生命周期。

    • 示例

      go 复制代码
      <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_0.xsd">
      </beans>
  • **META-INF/persistence.xml**(在 JPA 中)

    • 作用 :在 Java 持久化 API(JPA)中,persistence.xml 文件包含了数据源、实体管理器工厂和 JPA 的其他配置。这个文件一般放在 META-INF/ 目录下。

    • 示例

      go 复制代码
      <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
          <persistence-unit name="myJpaUnit">
              <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
              <jta-data-source>java:/MyDataSource</jta-data-source>
              <class>com.example.MyEntity</class>
          </persistence-unit>
      </persistence>
  • META-INF/manifest.mf

    • 作用 :在 OSGi(开放服务网关 initiative)中,META-INF/ 目录也用于存放 MANIFEST.MF 文件,这个文件描述了包的相关信息,如 Bundle-SymbolicName,Bundle-Version 等。
  • 加密算法相关的文件

    • 作用 :在一些使用加密功能的 Java 应用中,META-INF 目录还可能包含一些与加密相关的文件,例如签名证书、私钥、公钥、加密算法配置等。

    • 例如,JCE(Java Cryptography Extension)使用 META-INF 中的策略文件来指定可用的加密算法。

    总结

    META-INF 目录是 Java 项目中的重要文件夹,通常用于存放与 Java 应用的元数据、配置、服务发现、加密算法等相关的文件。它对于支持 JAR 文件的服务发现、插件机制、自动化配置等非常重要,特别是在使用 Spring 或 JPA 等框架时经常会遇到。在打包成 JAR 文件时,META-INF 会被保留下来,从而使得应用能够根据这些配置文件进行运行时的动态行为调整。

相关推荐
向上的车轮1 小时前
Spring Boot微服务架构(十一):独立部署是否抛弃了架构优势?
spring boot·微服务·架构
不吃饭的猪1 小时前
记一次运行spark报错
大数据·分布式·spark
qq_463944861 小时前
【Spark征服之路-2.1-安装部署Spark(一)】
大数据·分布式·spark
昭阳~2 小时前
Kafka深度技术解析:架构、原理与最佳实践
分布式·架构·kafka
向上的车轮2 小时前
Spring Boot微服务架构(十):Docker与K8S部署的区别
spring boot·微服务·架构
brzhang2 小时前
iOS 26 的备忘录,终于他娘的要支持 Markdown 了!
前端·后端·架构
ikun·2 小时前
Kafka 消息队列
分布式·kafka
ghie90902 小时前
Spring Boot使用Redis实现分布式锁
spring boot·redis·分布式
风麒麟3 小时前
13. springCloud AlibabaSeata处理分布式事务
分布式·spring·spring cloud
链上Sniper3 小时前
Python 区块链开发实战:从零到一构建智能合约
开发语言·网络·python·架构·区块链·php·智能合约