>  기사  >  Java  >  SpringBoot SpringEL 표현식을 사용하는 방법

SpringBoot SpringEL 표현식을 사용하는 방법

WBOY
WBOY앞으로
2023-05-15 12:04:061598검색

1. SpringEL 기본 소개

SpEL(SpEL)이란 무엇인가요?

  • Spring 3에서는 Spring 표현식 언어인 SpringEL이 도입되었습니다. SpEL은 Bean을 어셈블하는 강력하고 간결한 방법입니다.

  • SpringEL은 런타임 중에 실행되는 표현식을 통해 속성이나 생성자에 값을 어셈블할 수 있습니다.

  • SpringEL은 JDK에서 제공하는 정적 상수를 호출하여 외부 속성 파일의 구성을 얻을 수 있습니다.

SpringEL을 사용하는 이유는 무엇입니까?

  • 일반적으로 구성 파일을 통해 주입되거나 Annotaton을 실제로 호출할 수 있는 Bean은 정적용으로 주입

  • 빈 A에 변수 A가 있으면 그 값은 빈 B의 변수 B를 기반으로 해야 합니다. 이 시나리오에서 정적 주입은 이러한 처리에 매우 무력합니다

  • 그리고 Spring3은 SpringEL을 완전히 추가합니다. 이 요구를 충족시키며, 다른 Bean의 필드에 값을 계산하고 할당할 수도 있습니다. SpringEL을 사용하는 방법은 SpringEL과 유사하다는 것을 알 수 있습니다. Spring EL의 사용은 EL 표현식의 사용과 매우 유사합니다

EL 표현식을 사용하면 JSP 페이지의 백그라운드에서 값을 더 쉽게 얻을 수 있으며 SpringEL은 EL 표현식의 값을 더 쉽게 얻을 수 있습니다. Spring 컨테이너의 Bean

  • EL은 ${}를 사용하고 SpringEL은 #{}를 사용하여 표현식을 선언합니다

  • 둘 사이의 주요 차이점

  • $은 외부에서 구성된 매개변수를 찾고 value ​​

# 해당 변수의 내용을 찾는 SpEL 표현식입니다

  • EL을 사용하지 않고 @value("constant")를 직접 사용하여 주입할 수도 있습니다. 이 작성 방법은 direct와 동일합니다. 할당

  • Spring에서 사용한다면 **@PropertySource("classpath:my.properties")** 해당 구성 파일 로드

    2. EL 표현식 - 기본 사용
  • # 配置文件
    com:
      codecoord:
        el:
          num: 1001
          name: el
          language:
            - java
            - spring
            - mysql
            - linux
          # 逗号分隔可以注入列表
          language02: java,spring,mysql,linux

    사용 간단한 값을 삽입하는 EL ​​

    /**
     * 注入简单值,直接注入不使用EL,EL不支持直接指定常量
     * 直接在EL中指定的常量会当做配置处理,和直接赋值等价
     */
    @Value("1432516744")
    private Integer no;
  • 구성 파일 속성 값 삽입 ​​
/**
 * 注入整型属性值
 */
@Value("${com.codecoord.el.num}")
private Integer num;
/**
 * 注入字符属性值
 */
@Value("${com.codecoord.el.name}")
private String name;

Inject 기본값

/**
 * 注入字符不存在属性值并指定默认值,默认值使用过冒号分隔 :
 * 注入常量其实就可以指定一个不存在的配置然后使用默认值,此处skill的值为java
 */
@Value("${com.codecoord.el.skill:java}")
private String skill;

injection list

은 직접 구성 파일의 배열 구문 형식 삽입 목록을 지원하지 않습니다

쉼표로 구분된 구성을 식별할 수 있으며 스프링 기본값은 구분된

    // 错误写法:不支持直接注入yml列表格式语法列表
    @Value("${com.codecoord.el.language}")
    private List<String> listLanguage;
    @Value("${com.codecoord.el.language}")
    private String[] strLanguage;
    /**
     * 支持,分隔的注入列表
     */
    @Value("${com.codecoord.el.language02}")
    private List<String> listLanguage02;
    @Value("${com.codecoord.el.language02}")
    private String[] strLanguage02;
  • 전체 참조는 다음과 같습니다

    구성 파일
  • server:
      port: 8888
    com:
      codecoord:
        el:
          num: 1001
          name: el
          language:
            - java
            - spring
            - mysql
            - linux
          # 逗号分隔可以注入列表
          language02: java,spring,mysql,linux
  • 속성 구성 클래스

    import lombok.Data;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    
    @Data
    @Component
    public class ElConfig {
        /**
         * 注入简单值,直接注入不使用EL,EL不支持直接指定常量
         * 直接在EL中指定的常量会当做配置处理,和直接赋值等价
         */
        @Value("1432516744")
        private Integer no;
        /**
         * 注入整型属性值
         */
        @Value("${com.codecoord.el.num}")
        private Integer num;
        /**
         * 注入字符属性值
         */
        @Value("${com.codecoord.el.name}")
        private String name;
        /**
         * 注入字符不存在属性值并指定默认值,默认值使用过冒号分隔 :
         * 注入常量其实就可以指定一个不存在的配置然后使用默认值,此处skill的值为java
         */
        @Value("${com.codecoord.el.skill:java}")
        private String skill;
        /// 不支持直接注入列表
        /*@Value("${com.codecoord.el.language}")
        private List<String> listLanguage;
        @Value("${com.codecoord.el.language}")
        private String[] strLanguage;*/
        /**
         * 支持,分隔的注入列表
         */
        @Value("${com.codecoord.el.language02}")
        private List<String> listLanguage02;
        @Value("${com.codecoord.el.language02}")
        private String[] strLanguage02;
    }

    구성 클래스를 컨트롤러에 삽입한 다음 인터페이스 테스트 결과는 다음과 같습니다
  • {
     "no": 1432516744,
     "num": 1001,
     "name": "el",
     "skill": "java",
     "listLanguage02": [
      "java",
      "spring",
      "mysql",
      "linux"
     ],
     "strLanguage02": [
      "java",
      "spring",
      "mysql",
      "linux"
     ]
    }
3. SpringEL-기본 사용법

1. SpEL을 사용하여 간단한 값을 주입하는 것은 기본적으로 일반 EL 주입을 사용하는 것과 동일합니다

2. SpEl 주입 맵

구성 파일이 필요합니다. 그렇지 않으면 삽입이 실패합니다.

# SpEl
spEl:
  mapInject: "{"name": "SpEl", "website": "http://www.codeocord.com"}"

Java 클래스에서 먼저 ${spEl.mapInject}를 사용하여 문자열 값을 삽입하고 #{}를 구문 분석합니다. map

@Value("#{${spEl.mapInject}}")
private Map<String, String> mapInject;

3으로 변환합니다. SpEl은 list
  • EL을 통해 listI를 주입하는 것 외에도 #{${}.split("separator")}를 List에 주입하는 방법을 사용할 수도 있습니다

예를 들어 구성 파일에서는 #을 사용하여 구분합니다.

    spEl:
      listInject: "44#11#99#100"
  • Java 클래스에서는 먼저 ${spEl.listInject}를 사용하여 문자열 값을 삽입하고 내용을 작은따옴표로 묶은 다음 분할 메서드를 사용하여 구분합니다. 문자열

    팁: 빈 문자열을 기본값으로 지정하면 됩니다

    @Value("#{"${spEl.listInject:}".split("#")}")
     private List<String> listInject;
  • 4. 동적 주입
  • 위 주입은 모두 동적 주입이라고 하는 Spring 컨테이너의 정보 주입을 지원합니다. . 동적 주입 클래스는 다음과 같습니다

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    @Component
    @Data
    public class SpElConstant {
        private String name = "SpElConstant-name";
        private String nickname = "tianxin";
        private int num = 100;
        private List<String> product = new ArrayList<String>() {{
            add("huaweiMate30Pro");
            add("xiaomi10x5g");
        }};
        private Map<String, String> productMap = new HashMap<String, String>() {{
            put("huaweiMate30Pro", "5999");
            put("xiaomi10x5g", "4999");
        }};
        private List<City> cityList = new ArrayList<City>() {{
            add(new City("深圳", 1000L));
            add(new City("杭州", 2000L));
            add(new City("贵阳", 900L));
        }};
    
        public String showProperty() {
            return "showProperty-无参数";
        }
    
        public String showProperty(String name) {
            return "showProperty-" + name;
        }
    
        @Data
        @AllArgsConstructor
        static class City {
            private String name;
            private long population;
        }
    }
  • SpEl은 작업을 지원하거나 지원하지 않습니다


객체 자동 주입과 유사하게 인스턴스의 동적 주입을 지원합니다

SPL은 구성 파일에 구성 직접 주입을 지원하지 않습니다

  • 정적 및 인스턴스 호출 지원

  • Static 메서드: @Value("#{T(package.ClassName).ConstFieldName")

  • 정적 클래스 또는 상수 호출 지원
    • 연산자 작업 지원

  • 작업 컬렉션 지원

  • 쿼리 필터링 컬렉션 및 프로젝션 지원

  • 전체 주입 작업은 다음과 같습니다.

    import lombok.Data;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    import java.util.Map;
    
    @Data
    @Component
    public class SpElConfig {
        /// 不支持直接注入配置文件值
        /*@Value("#{com.codecoord.el.num}")
        private Integer num;*/
        /**
         * 对象注入
         */
        @Value("#{spElConstant}")
        private SpElConstant spElConstant;
        /**
         * 注入ID为spElConstant Bean中的STR常量/变量
         */
        @Value("#{spElConstant.name}")
        private String name;
        /**
         * 调用无参方法
         */
        @Value("#{spElConstant.showProperty()}")
        private String method1;
        /**
         * 有参接收字符串的方法
         */
        @Value("#{spElConstant.showProperty("Hell SpringEL")}")
        private String method2;
        /**
         * 方法返回的String为大写
         */
        @Value("#{spElConstant.showProperty().toUpperCase()}")
        private String method3;
        /**
         * 若使用method3这种方式,若果showProperty返回为null
         * 将会抛出NullPointerException,可以使用以下方式避免
         * 使用?.符号代表若然左边的值为null,将不执行右边方法
         */
        @Value("#{spElConstant.showProperty()?.toUpperCase()}")
        private String method4;
        /**
         * 注入math常量
         */
        @Value("#{T(java.lang.Math).PI}")
        private double pi;
        /**
         * 用random方法获取返回值
         */
        @Value("#{T(java.lang.Math).random()}")
        private double random;
        /**
         * 获取文件路径符号
         */
        @Value("#{T(java.io.File).separator}")
        private String separator;
        /**
         * 拼接字符串
         */
        @Value("#{spElConstant.nickname + " " + spElConstant.name}")
        private String concatString;
        /**
         * 对数字类型进行运算,spElConstant拥有num属性
         */
        @Value("#{3 * T(java.lang.Math).PI + spElConstant.num}")
        private double operation;
        /**
         * 进行逻辑运算
         */
        @Value("#{spElConstant.num > 100 and spElConstant.num <= 200}")
        private boolean logicOperation;
        /**
         * 进行或非逻辑操作
         */
        @Value("#{not (spElConstant.num == 100) or spElConstant.num <= 200}")
        private boolean logicOperation2;
        /**
         * 使用三元运算符
         */
        @Value("#{spElConstant.num > 100 ? spElConstant.num : spElConstant.num + 100}")
        private Integer logicOperation3;
        /**
         * 获取下标为0的元素
         */
        @Value("#{spElConstant.product[0]}")
        private String str;
        /**
         * 获取下标为0元素的大写形式
         */
        @Value("#{spElConstant.product[0]?.toUpperCase()}")
        private String upperStr;
        /**
         * 获取map中key为hello的value
         */
        @Value("#{spElConstant.productMap["hello"]}")
        private String mapValue;
        /**
         * 根据product下标为0元素作为key获取testMap的value
         */
        @Value("#{spElConstant.productMap[spElConstant.product[0]]}")
        private String mapStrByproduct;
        /**
         * 注入人口大于等于1000人口的城市
         */
        @Value("#{spElConstant.cityList.?[population >= 1000]}")
        private List<SpElConstant.City> cityList;
        /**
         * 注入人口等于900人口的城市
         */
        @Value("#{spElConstant.cityList.?[population == 900]}")
        private SpElConstant.City city;
        /**
         * 注入人口大于等于1000人口的城市,且只保留城市名称
         */
        @Value("#{spElConstant.cityList.?[population >= 1000].![name]}")
        private List<String> cityName;
    }

    삽입 결과
  • {
     "spElConstant": {
      "name": "SpElConstant-name",
      "nickname": "tianxin",
      "num": 100,
      "product": [
       "huaweiMate30Pro",
       "xiaomi10x5g"
      ],
      "productMap": {
       "xiaomi10x5g": "4999",
       "huaweiMate30Pro": "5999"
      },
      "cityList": [
       {
        "name": "深圳",
        "population": 1000
       },
       {
        "name": "杭州",
        "population": 2000
       },
       {
        "name": "贵阳",
        "population": 900
       }
      ]
     },
     "name": "SpElConstant-name",
     "method1": "showProperty-无参数",
     "method2": "showProperty-Hell SpringEL",
     "method3": "SHOWPROPERTY-无参数",
     "method4": "SHOWPROPERTY-无参数",
     "pi": 3.141592653589793,
     "random": 0.19997238292235787,
     "separator": "",
     "concatString": "tianxin SpElConstant-name",
     "operation": 109.42477796076938,
     "logicOperation": false,
     "logicOperation2": true,
     "logicOperation3": 200,
     "str": "huaweiMate30Pro",
     "upperStr": "HUAWEIMATE30PRO",
     "mapValue": null,
     "mapStrByproduct": "5999",
     "cityList": [
      {
       "name": "深圳",
       "population": 1000
      },
      {
       "name": "杭州",
       "population": 2000
      }
     ],
     "city": {
      "name": "贵阳",
      "population": 900
     },
     "cityName": [
      "深圳",
      "杭州"
     ]
    }
  • Spring은 외부 속성 파일을 작동합니다

    <!-- 首先通过applicaContext.xml中<util:properties>增加properties文件 -->
    <!-- 注意需要引入Spring的util schemea命名空间和注意id属性,id属性将在SpringEL中使用 -->
    <util:properties id="db" location="classpath:application.properties"/>
    public class TestSpringEL {
     // 注意db为xml文件中声明的id
     @Value("#{db["jdbc.url"]}")
     private String propertiesValue;
    }

    SpringEL은 사용될 때 문자열일 뿐입니다. 디버깅 및 문제 해결이 쉽지 않습니다. 테스트를 위해 구문을 확인할 수 있는 IDE가 없습니다. 오류 발생 시 감지하기 어렵기 때문에 SpringEL을 통해 복잡한 표현식을 삽입하는 것은 권장되지 않습니다. 필요한 경우가 아니면 SpEl의 복잡한 주입을 사용하지 않는 것이 좋습니다. 문제 해결에는 명확하고 읽기 쉬운 코드가 더 중요하고 도움이 됩니다.
4. 자동 속성 주입

위는 모두 @ConfigurationProperties를 통해 지정할 수 있는 지정된 필드를 통해 주입됩니다. 자동으로 주입됩니다

org.springframework.boot.context.properties.ConfigurationProperties

구성 클래스

user:
  id: ${random.uuid}
  name: autowire
  address: unknown
  website: www.codecoord.com
  age: ${random.int}

자동 속성 주입 클래스

프런트 엔드를 접두사를 통해 사용자로 지정하면 이름에 따라 사용자 뒤의 유형이 주입됩니다

주의하세요 setter 메소드를 제공해야 합니다

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "user")
@Data
public class UserConfig {
    private String id;
    private String name;
    private String address;
    private String website;
    private Integer age;
}

可以通过@EnableConfigurationProperties(value = UserConfig.class)将UserConfig再次强制注入,问题出现在如果UserConfig为第三方jar包内的配置类,则可能出现属性没有注入情况,所以可以指定注入

위 내용은 SpringBoot SpringEL 표현식을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제