Record a simple implementation of adding switches to the configuration file

Record a simple implementation of adding switches to the configuration file

Scene description:

Add a usage time to the program. After a few days, the program will not be accessible normally.

Possible implementation:

1. When the program starts, a scheduled task is started, and the program is destroyed after the specified time. However, if the program is restarted... you still need some scheduled task code. If you can't write it, don't write it. Let's go through it first.

2. Add a key to redis and add an expiration time to the key;

When the program starts (when loading beans), add a key to redis and set the expiration time. When the program restarts within the expiration time, if there is this key, it will not be added to redis;

Both of the above methods have bugs, but at the moment I can only solve them this way.

Let’s record the implementation method for now:

Configuration switches

Add a switch to the configuration file

Adding a price tag to the configuration file indicates whether to enable specific functions.

login: true

Then check whether the configuration file switch is turned on:

Implemented through annotations in spring:

import com.hmrs.filter.LoginFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LoginFilterWebConfig {

 @LoginTaskConditionOnProperTy(value = "login" ,havingValue = "true")
    @Bean
    public LoginFilter buildFilter() {
        return new LoginFilter();
    }
}

If there is this configuration in the configuration file and the value is true, it means turning on this filter;

Why turn on this filtering?-----Interception request:

The condition for interception is whether there is a specified key in redis

Customize an annotation

import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional(LoginFilterCondition.class)
public @interface LoginTaskConditionOnProperTy {
    String value();
    String prefix() default "";
    String havingValue() default "";
    boolean matchIfMissing() default false;
    boolean relaxedNames() default true;
}

What does the filter look like?

import com.alibaba.fastjson2.JSONObject;
import com.hmrs.comm.BaseResult;
import com.hmrs.service.RedisRWService;
import com.hmrs.util.HmrsUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author Gavin
 */
@Slf4j
public class LoginFilter implements Filter {

    @Autowired
    private RedisRWService redisRWService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        if (redisRWService.hasKey("Gavin")){
            log.info("redis中已有key");
        }else{
            log.info("设置redis的key");
            redisRWService.saveObjData("Gavin", "Gavin");
            redisRWService.setKeyExpireTime("Gavin", 72);
        }

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       if (request instanceof HttpServletRequest){
           if (redisRWService.hasKey("Gavin")) {
               log.info("Gavin过滤器已生效");
               chain.doFilter(request, response);
           } else {
               log.info("Gavin过滤器已失效");
               BaseResult baseResult = HmrsUtils.setHttpBaseResult(400, "failed", "接口已失效");
               HmrsUtils.returnJson((HttpServletResponse) response, JSONObject.toJSONString(baseResult));
               return;
           }
       }else{
           return ;
       }

    }

    @Override
    public void destroy() {

    }
}

After having the filter, we need to inject this filter to make it effective:

import com.hmrs.filter.LoginFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;



//@ConditionalOnProperty(prefix = "login", name = "enable", havingValue = "true")
@Configuration
public class LoginFilterWebConfig {

    /**
     * 注册LoginFilter
     *
     * @return 返回实例
     */
    @LoginTaskConditionOnProperTy(value = "login" ,havingValue = "true")
    @Bean
    public LoginFilter buildFilter() {
        return new LoginFilter();
    }
}

The question is when will it take effect? ​​This is controlled by us. If we directly add annotations to the above LoginFilterWebConfig

@ConditionalOnProperty(prefix = “login”, name = “enable”, havingValue = “true”)

Since spring manages it by itself, it does not follow what we want. Simply put, the filter will take effect regardless of whether the switch is turned on or not, so we need to customize an annotation, and then inject this filter LoginFilter under certain conditions.

When customizing the annotation LoginTaskConditionOnProperTy, we need to import a class: LoginFilterCondition—that is, with this annotation, whether the bean is loaded will be customized according to the matching situation under the imported class by imprt:

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.MultiValueMap;

import java.util.List;

public class LoginFilterCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        MultiValueMap<String, Object> allAnnotationAttributes = metadata.getAllAnnotationAttributes(LoginTaskConditionOnProperTy.class.getName());
        List<Object> objectList = allAnnotationAttributes.get("value");
        List<Object> havingValue = allAnnotationAttributes.get("havingValue");
        String property = context.getEnvironment().getProperty((String) objectList.get(0));
        if (property.equals(havingValue.get(0))){
            return true;
        }
        return false;
    }
}

Finally, after we turn on the switch:

com.hmrs.filter.LoginFilter - key already exists in redis

After turning off the switch: the bean of this class is not loaded.

Guess you like

Origin blog.csdn.net/weixin_54061333/article/details/132054053