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")** を使用して、対応する構成ファイルをロードできます
# 配置文件 com: codecoord: el: num: 1001 name: el language: - java - spring - mysql - linux # 逗号分隔可以注入列表 language02: java,spring,mysql,linuxEL を使用して単純な値を挿入する
/** * 注入简单值,直接注入不使用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;
spEl: listInject: "44#11#99#100"
ヒント: 空の状況を避け、デフォルト値として空の文字列
@Value("#{"${spEl.listInject:}".split("#")}") private List<String> listInject;
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 は操作をサポートし、サポートしません
#サポート操作コレクション
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": [ "深圳", "杭州" ] }
<!-- 首先通过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 の複雑なインジェクションを使用することはお勧めしません。明確で読みやすいコードの方が重要であり、トラブルシューティングに役立ちます。
org.springframework.boot.context.properties.ConfigurationPropertiesConfiguration 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 サイトの他の関連記事を参照してください。