日常小问题

配置文件加载到静态文件中去

    private static String value;

    @Value("${version}")
    public void setValue(String version){
        value = version;
    }

实现Runable类无法使用自动注入

因为Java默认多线程不能自动注入

可以手动注入解决问题



import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

之后直接调用这个类的方法就可以了

 private UserinfoService userinfoService;

    public Running() {
        this.userinfoService = ApplicationContextProvider.getBean(UserinfoService.class);
    }

new方法中加入SpringBoot的自动注入方式

@Component
public class ServerConfig implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (ServerConfig.applicationContext ==null){
            ServerConfig.applicationContext = applicationContext;
        }
    }

    // 获取applicationContext
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    // 通过name获取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    // 通过class获取Bean.
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    // 通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

在new的方法下

    private static HookFromHandler hookFromHandler;
    private static INettyLogService nettyLogService;
    static {
        hookFromHandler = ServerConfig.getBean(HookFromHandler.class);
        nettyLogService = ServerConfig.getBean(INettyLogService.class);
    }

LocalDate返回中有T,返回时间为空,对象接不到

//未测试
@Configuration
public class LocalDateTimeSerializerConfig {

    //方法 一

    @Bean
    public LocalDateTimeSerializer localDateTimeDeserializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
    }

    //方法 二

 /*   @Bean(name = "mapperObject")
    public ObjectMapper getObjectMapper() {
        ObjectMapper om = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        om.registerModule(javaTimeModule);
        return om;
    }*/
}



//已测
使用注解  
  @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime positionTime;

跨域拦截器不生效

当自定义拦截器和跨域拦截器一起使用时,自定义拦截器的Order级别要比跨域拦截器的数字低,导致跨域拦截器不生效,应提高跨域拦截器的执行。

1. 提高Order

2. 将跨域定在过滤器中

异步失效情况

异步实际上使用的是代理做到的,SpringBoot会默认检测到注解,会建立一个代理类去继承备异步注解的方法,当调用时实际上使用的是代理类。

1.类必须是被@Component注解修饰

2. 类必须不能被@Configuration (未找到原因)

3. 不能使用在自身类中,自己掉自己不会走代理

4. 调用必须通过注入形式,不然SpringBoot的代理拿不到

Annotation that marks a method as a candidate for asynchronous execution. Can also be used at the type level, in which case all of the type's methods are considered as asynchronous. Note, however, that @Async is not supported on methods declared within a @Configuration class.
In terms of target method signatures, any parameter types are supported. However, the return type is constrained to either void or java.util.concurrent.Future. In the latter case, you may declare the more specific org.springframework.util.concurrent.ListenableFuture or java.util.concurrent.CompletableFuture types which allow for richer interaction with the asynchronous task and for immediate composition with further processing steps.
A Future handle returned from the proxy will be an actual asynchronous Future that can be used to track the result of the asynchronous method execution. However, since the target method needs to implement the same signature, it will have to return a temporary Future handle that just passes a value through: e.g. Spring's AsyncResult, EJB 3.1's javax.ejb.AsyncResult, or java.util.concurrent.CompletableFuture.completedFuture(Object).
Since:
3.0
See Also:
AnnotationAsyncExecutionInterceptor, AsyncAnnotationAdvisor
Author:
Juergen Hoeller, Chris Beams

继承OncePerRequestFilter自动注入不生效

属性上加入构造器


    private RedisCacheUtils redisCacheUtils;

    public PostFilter(RedisCacheUtils redisCacheUtils) {
        this.redisCacheUtils = redisCacheUtils;
    }

配置类中配置

@Configuration
public class WebConfig{

    @Autowired
    private RedisCacheUtils redisCacheUtils;

    @Bean
    public FilterRegistrationBean WebFilterDemo(){
        //配置过滤器
        FilterRegistrationBean frBean = new FilterRegistrationBean();
        frBean.setFilter(new PostFilter(redisCacheUtils));
        frBean.addUrlPatterns("/*");
        frBean.setName("webFilterDemo");
        //springBoot会按照order值的大小,从小到大的顺序来依次过滤。
//        frBean.setOrder(0);
        return frBean;
    }
}

Swagger配置

配置类


import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

@Configuration
@EnableSwagger2
@Slf4j
public class SwaggerConfig {
    @Value("${custom.swaggerEnable}")
    private Boolean enabled;

    /*访问地址 http://localhost:8099/swagger-ui.html*/

    @Bean
    public Docket authApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .enable(enabled)
                .apiInfo(apiInfo("描述 处罚单"))
                .select()
                // 扫描所有有注解的api,用这种方式更灵活
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // 扫描指定包中的swagger注解
                .apis(RequestHandlerSelectors.basePackage("com.penalty.controller"))
                .build()
                .groupName("处罚单")
                .pathMapping("/")
                .securitySchemes(securitySchemes())
                .securityContexts(securityContexts());
    }


    @SuppressWarnings("deprecation")
    private static Optional<? extends Class<?>> declaringClass(RequestHandler requestHandler) {
        return Optional.ofNullable(requestHandler.declaringClass());
    }

    /**
     * 校验基础包
     */
    private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {
        return input -> {
            for (String strPackage : basePackage.split(";")) {
                boolean isMatch = input.getPackage().getName().startsWith(strPackage);
                if (isMatch) {
                    return true;
                }
            }
            return false;
        };
    }
    // ---------------------改写RequestHandlerSelectors中方法----------------------------

    private List<SecurityScheme> securitySchemes() {
        List<SecurityScheme> l = new ArrayList<>();
        l.add(new ApiKey("authorization", "authorization", "header"));
        l.add(new ApiKey("loginType", "loginType", "header"));
        return l;
    }

    private List<SecurityContext> securityContexts() {
        List<SecurityContext> l = new ArrayList<>();
        l.add(SecurityContext.builder()
                .securityReferences(defaultAuth())
                .forPaths(PathSelectors.regex("^(?!/demo|/auth).*$"))
                .build());
        return l;
    }

    List<SecurityReference> defaultAuth() {
        AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
        AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
        authorizationScopes[0] = authorizationScope;
        List<SecurityReference> l = new ArrayList<>();
        l.add(new SecurityReference("authorization", authorizationScopes));
        l.add(new SecurityReference("loginType", authorizationScopes));
        return l;
    }

    /**
     * api信息
     */
    private ApiInfo apiInfo(String description) {
        return new ApiInfoBuilder().title("处罚单管理").contact(new Contact("经纬智联开发部", null, null))
                .description(description).version("1.0.0").build();
    }

}

加入Web拦截

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 通用配置
 */
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {

    @Autowired
    private RepeatSubmitInterceptor repeatSubmitInterceptor;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // swagger配置
        registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
    }
}

restFul配置

RESTFUL风格类上不能加@ApiModel

private T data;泛型不能加注解

必须要用泛型模式<T>,否则不显示

@Data
public class WebResponse<T> {
	/**
	 * 0-成功;其他-失败 必填
	 */
	@ApiModelProperty(value = "0-成功;其他-失败 必填",name = "code",example = "200",required = true)
	private int result;
	/**
	 * 失败时的错误信息 非必填
	 */
	@ApiModelProperty(value = "失败时的错误信息 非必填",name = "error_msg")
	private String error_msg;
	/**
	 * 成功时的手机号信息,说明如下表 非必填
	 */
	private T data;

	public WebResponse() {
		this(0, null);
	}

	public WebResponse(int result, String resultMsg) {
		this(result, resultMsg, null);
	}

	public WebResponse(T data) {
		this(0, null, data);
	}

	public WebResponse(int result, String resultMsg, T data) {
		this.result = result;
		if (result != 0) {
			this.error_msg = resultMsg;
		}
		this.data = data;

	}

	public static WebResponse error(BaseError baseError){
		return new WebResponse(baseError.getErrorCode(), baseError.getErrMsg());
	}

	public static WebResponse success(){
		return new WebResponse();
	}

	public static <T> WebResponse<T> success(T o){
		return new WebResponse(o);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值