专栏首页爱撸猫的杰Spring Boot Web 自定义注解篇(注解很简单很好用)

Spring Boot Web 自定义注解篇(注解很简单很好用)

自从spring 4.0 开放以后,可以添加很多新特性的注解了。使用系统定义好的注解可以大大方便的提高开发的效率。

下面我贴一段代码来讲解注解:

通过小小的注解我们支持了以下功能:

  • 使 spring.jackson.date-format 属性支持 JDK8 日期格式化
  • 解决 request.getInputStream() 一次读取后失效痛点
  • 国际化支持
  • 全局跨域支持
  • 接口加密/解密
  • 防XSS攻击
  • 分布式限流/分布式锁支持

我们通过自定义@EnableCorsFilter 来看一下跨域是如何支持的:

package com.battcn.boot.request.annotation;

import com.battcn.boot.request.configuration.cors.CorsFilterAutoConfiguration;
import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

/**
 * 开启跨域支持
 *
 * @author Levin
 * @since 2019-01-01
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({CorsFilterAutoConfiguration.class})
public @interface EnableCorsFilter {

}

@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。  如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。 

CorsFilterAutoConfiguration类(具体实现)
package com.battcn.boot.request.configuration.cors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import static com.battcn.boot.request.utils.StringUtils.defaultString;

/**
 * Cors 跨域支持
 *
 * @author Levin
 * @since 2017/12/5 0005
 */
@Configuration
@EnableConfigurationProperties(value = {CorsFilterProperties.class})
public class CorsFilterAutoConfiguration {

    private static final String PATH = "/**";

    private final CorsFilterProperties properties;

    @Autowired
    public CorsFilterAutoConfiguration(CorsFilterProperties properties) {
        this.properties = properties;
    }


    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin(defaultString(properties.getOrigin(), CorsConfiguration.ALL));
        corsConfiguration.addAllowedHeader(defaultString(properties.getAllowedHeader(), CorsConfiguration.ALL));
        corsConfiguration.addAllowedMethod(defaultString(properties.getMethod(), CorsConfiguration.ALL));
        // 是否发送 Cookie 信息
        corsConfiguration.setAllowCredentials(properties.getAllowCredentials());
        if (properties.getMaxAge() != null) {
            corsConfiguration.setMaxAge(properties.getMaxAge());
        }
        if (properties.getExposedHeader() != null) {
            corsConfiguration.addExposedHeader(properties.getExposedHeader());
        }
        return corsConfiguration;
    }

    /**
     * 跨域过滤器
     *
     * @return Cors过滤器
     */
    @Bean
    @ConditionalOnMissingBean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration(defaultString(properties.getPath(), PATH), buildConfig());
        return new CorsFilter(source);
    }

}
@ConditionalOnMissingBean 属性相同,自动生成加载

@Configuration   Ioc加载到bean里

@EnableConfigurationProperties   加载class配置项
@ConfigurationProperties  加载具体的配置参数


CorsFilterProperties配置类
package com.battcn.boot.request.configuration.cors;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.lang.Nullable;

/**
 * Core 跨域相关配置
 *
 * @author Levin
 * @since 2017/12/5 0005
 */
@Data
@ConfigurationProperties("request.cors")
public class CorsFilterProperties {

    private Boolean enabled;
    private String path;
    private String origin;
    private String allowedHeader;
    private String method;
    private String exposedHeader;

    @Nullable
    private Boolean allowCredentials;

    @Nullable
    private Long maxAge;

}

 application.properties配置项

我在类属性里定义的maxAge,但是application里面显示的是max-age,会自动帮做转换,如果使用maxAge属性参数也是可以取到值的(是不是spring帮做了匹配查找)。

完成以上操作,只要在SpringApplication 启动加上@EnableCorsFilter  就可以实现跨域了。

maven调用以下是快速使用方法:

<dependency>
    <groupId>com.battcn</groupId>
    <artifactId>request-spring-boot-starter</artifactId>
    <version>1.0.8-RELEASE</version>
</dependency>

感谢唐亚峰提供的工具类。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Tomcat 类加载器打破双亲委派模型

    1. 什么是类加载机制? 2. 什么是双亲委任模型? 3. 如何破坏双亲委任模型? 4. Tomcat 的类加载器是怎么设计的?

    爱撸猫的杰
  • ActiveMQ的断线重连机制

    断线重连机制是ActiveMQ的高可用性具体体现之一。ActiveMQ提供failover机制去实现断线重连的高可用性,可以使得连接断开之后,不断的重试连接到一...

    爱撸猫的杰
  • 基于Twitter的Snowflake算法实现分布式高效有序ID生产黑科技(无懈可击)

    参考美团文档:https://tech.meituan.com/2017/04/21/mt-leaf.html

    爱撸猫的杰
  • Shedlock初体验

        正题:单体应用直接用java的lock就可以了,但是分布式锁,一般要么自己实现,要么使用第三方工具。以下简单说下原理:

    尚浩宇
  • Spring security笔记4/4: 自定义成功和失败

    重命名 Case3Application.java 为 Case4Application.java

    tonglei0429
  • @EnableDiscoveryClient和@EnableEurekaClient的区别?

    @EnableDiscoveryClient和@EnableEurekaClient的区别?在前面的服务提供者的例子中我们是用@EnableEurekaClie...

    马克java社区
  • SpringSecurity权限管理,根据请求URL鉴权

    SpringSecurity和Shiro是两大权限框架,前者属于Spring家族,功能比较强,重量级的存在,新手搞的时候可能会经常遇到坑。后者比较轻量级,上手相...

    奋斗蒙
  • SpringCloud gateway跨域配置

    天涯泪小武
  • 基于spring security实现接口权限控制

    一、基于注解 (1)在security配置文件上配置@EnableGlobalMethodSecurity(prePostEnabled = true)注解 ...

    用户5166330
  • springboot scheduled并发配置

    本文介绍如何使用springboot的sheduled实现任务的定时调度,并将调度的任务实现为并发的方式。 1、定时调度配置scheduled 1)注册定时任务...

    用户1225216

扫码关注云+社区

领取腾讯云代金券