ホームページ  >  記事  >  Java  >  SpringBoot SpringEL 式の使用方法

SpringBoot SpringEL 式の使用方法

WBOY
WBOY転載
2023-05-15 12:04:061652ブラウズ

1. SpringEL の基本概要

SpringEL (SpEL) とは何ですか?

  • Spring3 では Spring 式言語 SpringEL が導入されました。SpEL は Bean を組み立てる強力かつ簡潔な方法です

  • SpringEL を渡すことができます式が実行されます実行時に、値をプロパティまたはコンストラクターにアセンブルします。

  • SpringEL は、JDK で提供される静的定数を呼び出して、外部プロパティ ファイルの構成を取得できます。

なぜ SpringEL を使用するのか?

  • 通常、設定ファイルまたはアノタトンを通じて注入される Bean は、実際には静的インジェクションと呼ぶことができます。

  • Bean A の変数 A の場合、その値は Bean B の B 変数に基づく必要があります。このシナリオでは、静的インジェクションはそのような処理には非常に無力です

  • Spring3 によって追加された SpringEL は、次のことができます。この要求を完全に満たし、さまざまな Bean のフィールドに値を計算して代入することもできます。非常に強力です。

SpringEL の使用方法?

  • SpringEL は、名前から EL に関連していることがわかります。SpringEL の使用は、EL 式の使用と非常に似ています。

  • EL 式の方が便利です。 JSP ページのバックグラウンドで値を取得する場合、SpringEL は Spring コンテナ内の Bean の値をより簡単に取得する場合

  • EL は ${} を使用しますが、SpringEL は # を使用します{}式を宣言します

#この 2 つの主な違いは、外部構成のパラメータを見つけて値を割り当てることです

  • # は、対応する変数の内容を見つけるための SpEL 式

  • EL を使用せずに @value ("constant") を直接使用して注入することもできます。この記述方法は直接代入と同等です。

  • 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;

デフォルト値を挿入する

/**
 * 注入字符不存在属性值并指定默认值,默认值使用过冒号分隔 :
 * 注入常量其实就可以指定一个不存在的配置然后使用默认值,此处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-Basic の使用法

1. SpEL を使用して単純な値を注入する方法は、基本的に通常の値を注入する場合と同じです。 EL インジェクション

2. SpEl インジェクション マップ


設定ファイルは二重引用符で囲む必要があります。そうしないと、インジェクションは失敗します。キーは一重引用符です。

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

    java クラスを最初に使用します ${spEl.mapInject} を使用して文字列値を挿入します。#{} は文字列値を解析し、マップ

    @Value("#{${spEl.mapInject}}")
    private Map<String, String> mapInject;
  • 3 に変換します。SpEl はリストを挿入します

## ただし、EL を通じて listI を注入することに加えて、#{${}.split("separator")} を使用して List

    を注入することもできます。
  • を構成ファイルに追加します。たとえば、# を使用して

  • spEl:
      listInject: "44#11#99#100"
  • Java クラスで、最初に ${spEl.listInject} を使用して文字列値を挿入し、コンテンツを囲みます。単一引用符で囲み、split メソッドを使用して文字列を区切ります

    ヒント: 空の状況を避け、デフォルト値として空の文字列

    @Value("#{"${spEl.listInject:}".split("#")}")
     private List<String> listInject;
  • 4 を指定できます。上記のインジェクションはすべて静的インジェクションですが、SpEl は動的インジェクションと呼ばれる 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")
    • 静的クラスまたは定数の呼び出しをサポート
    • オペレーター操作のサポート
  • #サポート操作コレクション

  • #クエリ フィルタリング コレクションとプロジェクションのサポート

  • #Inject完全な操作は次のとおりです

    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

Configuration class

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

Automatic Property Injection class

フロントエンドをユーザーとして指定します。 prefix まで、 user. の後の type は名前に従って挿入されます

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。