一、SpringEL-基础介绍

什么是SpringEL(SpEL)?Spring3中引入了Spring表达式语言—SpringEL,SpEL是一种强大,简洁的装配Bean的方式SpringEL可以通过运行期间执行的表达式将值装配到我们的属性或构造函数当中SpringEL可以调用JDK中提供的静态常量,获取外部Properties文件中的的配置

为什么要使用SpringEL?平常通过配置文件或Annotaton注入的Bean,其实都可以称为静态性注入如BeanA中有变量A,它的值需要根据BeanB的B变量为参考,在这场景下静态注入就对这样的处理显得非常无力而Spring3增加的SpringEL就可以完全满足这种需求,而且还可以对不同Bean的字段进行计算再进行赋值,功能非常强大

如何使用SpringEL?SpringEL从名字来看就能看出和EL是有点关系的,SpringEL的使用和EL表达式的使用非常相似EL表达式在JSP页面更方便地获取后台中的值,而SpringEL就是为了更方便获取Spring容器中的Bean的值EL使用${},而SpringEL使用是SpEL表达式,去寻找对应变量的内容也可以直接使用@value("常量")注入不使用EL,这样写法与直接赋值等价

如果是在Spring中使用可以使用@PropertySource("classpath:")加载对应配置文件

二、EL表达式-基础使用
逗号分隔可以注入列表language02:java,spring,mysql,linux

使用EL注入简单值

/***注入简单值,直接注入不使用EL,EL不支持直接指定常量*直接在EL中指定的常量会当做配置处理,和直接赋值等价*/@Value("1432516744")privateIntegerno;

注入配置文件属性值

/***注入整型属性值*/@Value("${}")privateIntegernum;/***注入字符属性值*/@Value("${}")privateStringname;

注入默认值

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

注入列表不支持直接配置文件中数组语法格式注入列表可以识别使用逗号,分隔的配置,spring默认以,分隔

//错误写法:不支持直接注入yml列表格式语法列表@Value("${}")privateListStringlistLanguage;@Value("${}")privateString[]strLanguage;/***支持,分隔的注入列表*/@Value("${}")privateListStringlistLanguage02;@Value("${}")privateString[]strLanguage02;

完整参考如下配置文件

server:port:8888com:codecoord:el:num:1001name:ellanguage:-java-spring-mysql-linuxSpElspEl:mapInject:"{'name':'SpEl','website':''}"

java类中先使用${}注入字符串值,{${}}")privateMapString,StringmapInject;

SpEl注入list除了可以通过EL注入listI外,也可以使用分隔

spEl:listInject:"4499{'${:}'.split('{T().ConstFieldName")支持调用静态类或常量支持运算符运算支持操作集合支持查询筛选集合和投影

注入完整操作如下

;;;;;@Data@ComponentpublicclassSpElConfig{///不支持直接注入配置文件值/*@Value("{spElConstant}")privateSpElConstantspElConstant;/***注入ID为spElConstantBean中的STR常量/变量*/@Value("{()}")privateStringmethod1;/***有参接收字符串的方法*/@Value("{().toUpperCase()}")privateStringmethod3;/***若使用method3这种方式,若果showProperty返回为null*将会抛出NullPointerException,可以使用以下方式避免*使用?.符号代表若然左边的值为null,将不执行右边方法*/@Value("{T().PI}")privatedoublepi;/***用random方法获取返回值*/@Value("{T().separator}")privateStringseparator;/***拼接字符串*/@Value("{3*T().PI+}")privatedoubleoperation;/***进行逻辑运算*/@Value("{not(==100)=200}")privatebooleanlogicOperation2;/***使用三元运算符*/@Value("{[0]}")privateStringstr;/***获取下标为0元素的大写形式*/@Value("{['hello']}")privateStringmapValue;/***根据product下标为0元素作为key获取testMap的value*/@Value("{?[population=1000]}");/***注入人口等于900人口的城市*/@Value("{?[population=1000].![name]}")privateListStringcityName;}

注入结果

{"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-HellSpringEL","method3":"SHOWPROPERTY-无参数","method4":"SHOWPROPERTY-无参数","pi":3.9793,"random":0.19997238292235787,"separator":"\\","concatString":"tianxinSpElConstant-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操作外部Properties文件

!--首先通过中util:properties增加properties文件--!--注意需要引入Spring的utilschemea命名空间和注意id属性,id属性将在SpringEL中使用--util:propertiesid="db"location="classpath:"/复制代码publicclassTestSpringEL{//注意db为xml文件中声明的id@Value("#{db['']}")privateStringpropertiesValue;}

SpringEL在使用时仅仅是一个字符串,不易于排错与测试,也没有IDE检查我们的语法,当出现错误时较难检测,复杂的表达式不建议通过SpringEL方式注入。在非必要情况下,不推荐使用SpEl的复杂注入,清晰可读的代码更为重要且有利于排查问题

四、属性自动注入

上述都是通过指定字段进行注入,可以通过@ConfigurationProperties指定前缀进行自动注入

配置类

user:id:${}name:autowireaddress:unknownwebsite::${}

自动属性注入类通过prefix指定前端为user,然后将会把user.后的类型按照名称进行注入注意必须要提供setter方法

;;;@Component@ConfigurationProperties(prefix="user")@DatapublicclassUserConfig{privateStringid;privateStringname;privateStringaddress;privateStringwebsite;privateIntegerage;}

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