springcloud 复习day2~[条件装配]

条件装配:

注解:@Condition

定义一个注解

import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;

/**
 * @author Gavin
 */
@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;
}

配置类:

在特定条件下加载bean

这里通过配置文件(元数据) 中特定的值来实现,也可以直接在LoginFilterCondition类中添加别的逻辑


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


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

    /**
     * 注册LoginFilter
     *  目的:当配置文件中有元数据 login 且值为 true时 装载LoginFilter 类
     * @return 返回实例
     */
    @LoginTaskConditionOnProperTy(value = "login" ,havingValue = "true")
    @Bean
    public LoginFilter buildFilter() {
        return new LoginFilter();
    }
}

做法—>实现Condition接口

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;

/**
 * @author Gavin
 */
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));
        return property.equals(havingValue.get(0));
    }
}

配置config


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


/**
 * @author Gavin
 */
//@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();
    }
}

LoginFilter类如下


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() {

    }
}

在Spring Boot中,针对@Conditional做了扩展,提供了更简单的使用形式,

扩展注解如下:
ConditionalOnBean/ConditionalOnMissingBean:容器中存在某个类或者不存在某个Bean时进行Bean装载

ConditionalOnClass/ConditionalOnMissingClass:classpath下存在指定类或者不存在指定类时进行Bean装载

ConditionalOnCloudPlatform:只有运行在指定的云平台上才加载指定的Bean

ConditionalOnExpression:基于SpEl表达式的条件判断

ConditionalOnJava:只有运行指定版本的Java才会加载Bean

ConditionalOnJndi:只有指定的资源通过JNDI加载后才加载Bean

ConditionalOnWebApplication/ConditionalOnNotWebApplication:如果是Web应用或者不是Web应用,才加载指定的Bean

ConditionalOnProperty:系统中指定的对应的属性是否有对应的值

ConditionalOnResource:要加载的Bean依赖指定资源是否存在于classpath中

ConditionalOnSingleCandidate:只有在确定了给定Bean类的单个候选项时才会加载Bean

上面的代码就可以简化为:

下面一点代码:

可打断点测试

import com.hmrs.filter.LoginFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


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

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

如果matchIfMissing的值为true,则没有匹配上不回加载,如果为false 则即使没有匹配上也会加载

自定义starter

基本依赖:

  <dependencies>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>3.11.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.7.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>2.7.12</version>
        </dependency>

    </dependencies>

配置类:


import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @author Gavin
 * 这里的前缀即配置文件中的前缀
 */
@ConfigurationProperties(prefix = "gavin.redisson")
public class RedissonProperties {


    private String host ="localhost";
    private String password ;

    private int port =6379;

    private boolean ssl;

    private Integer timeOut;
    public String getHost() {
        return host;
    }

    public Integer getTimeOut() {
        return timeOut;
    }

    public void setTimeOut(Integer timeOut) {
        this.timeOut = timeOut;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public boolean isSsl() {
        return ssl;
    }

    public void setSsl(boolean ssl) {
        this.ssl = ssl;
    }
}

根据配置类创建bean



import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

@Configuration
@ConditionalOnClass(Redisson.class)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonAutoConfiguration {

    @Bean
    public RedissonClient redissonClient(RedissonProperties redissonProperties) {
        Config config = new Config();
        String prefix = "redis://";
        if (redissonProperties.isSsl()) {
            prefix = "rediss://";
        }
        SingleServerConfig singleServerConfig = config.useSingleServer().setAddress(prefix + redissonProperties.getHost() + ":" + redissonProperties.getHost()).setConnectTimeout(redissonProperties.getTimeOut());
        if (!StringUtils.isEmpty(redissonProperties.getPassword())) {
            singleServerConfig.setPassword(redissonProperties.getPassword());
        }
        return Redisson.create(config);
    }
}

最后重要的一步:

在resources下创建META-INF/spring,factories文件,使得Spring Boot程序可以扫描到该文件完成自动装配,

#在resources下创建META-INF/spring.factories文件,使得Spring Boot程序可以扫描到该文件完成自动装配,key和value对应如下
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.gavin.RedissonAutoConfiguration

最后打包即可,然后引用该包,最后在配置文件中按需配置即可

相关推荐

  1. springcloud 复习day2~[条件装配]

    2024-03-25 21:32:06       41 阅读
  2. springcloud 复习day1~[自动装配]

    2024-03-25 21:32:06       45 阅读
  3. 复习Day2_

    2024-03-25 21:32:06       43 阅读
  4. 详解 Spring Boot 条件装配

    2024-03-25 21:32:06       49 阅读
  5. Python学习之复习MySQL-Day2(DML)

    2024-03-25 21:32:06       78 阅读
  6. SpringCloud框架的复习(面试)

    2024-03-25 21:32:06       28 阅读
  7. Day28:学习SpringCloud

    2024-03-25 21:32:06       39 阅读
  8. Day26:学习SpringCloud

    2024-03-25 21:32:06       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-25 21:32:06       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-25 21:32:06       100 阅读
  3. 在Django里面运行非项目文件

    2024-03-25 21:32:06       82 阅读
  4. Python语言-面向对象

    2024-03-25 21:32:06       91 阅读

热门阅读

  1. 【Caddy】Caddy实践1——此网站无法提供安全连接

    2024-03-25 21:32:06       44 阅读
  2. 将表格数据导出 Excel 格式的数据方法(2)

    2024-03-25 21:32:06       42 阅读
  3. ruoyi-nbcio-plus后端里mapstruct-plus和lombok的使用

    2024-03-25 21:32:06       42 阅读
  4. 代码随想录第四天 链表Part02

    2024-03-25 21:32:06       46 阅读
  5. i++是否线程安全?

    2024-03-25 21:32:06       39 阅读
  6. 数据库

    数据库

    2024-03-25 21:32:06      40 阅读
  7. GAN 生成式对抗网络介绍

    2024-03-25 21:32:06       43 阅读