spring高级装配-运行时注入

it2022-06-27  91

<bean id="sgtPeppers" class="soundsystem.BlandDisc" c:_title="Sgt.Pepper's Lonely Hearts" c:_artist="The Beatles" />

上述配置中是sgtPepper的属性值是写死的,有时候这些值我们想在运行时再确定,那么要如何实现呢,spring提供了两种方式可以做到运行时注入:属性占位符,Spring表达式语言. 1 注入外部的值

package com.soundsystem; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; @Configuration @PropertySource("classpath:/com/soundsystem/app.properties") public class ExpressiveConfig { @Autowired Environment env; @Bean public BlankDisc disc{ return new BlankDisc(env.getProperty("disc.titile"),env.getProperty("disc.artist")); } }

备注:Environment的getProperty()有四个重载的变种形式: String getProperty(String key); //若获取不到值将会返回null String getProperty(String key,String default); T getProperty(String key,Class type);//若获取不到值将会返回null T getProperty(String key,Class type, T defaultValue); 此外还有一些其他的方法如下: String getRequiredProperty(); //获取不到值时将会抛出IllegalStateException异常 boolean containsProperty();//判断某个属性是否存在 T getPropertyAsClass(String key, Class type); //将属性解析为类 String[] getActiveProfiles() //返回激活profile名称的数组 String[] getDefaultProfiles();//返回默认profile名称的数组 String[] acceptsProfiles(String… profiles);//如果environment支持给定profile的话,就返回true;

解析属性占位符

<bean id="sgtPeppers" class="soundsystem.BlankDisc" c:_title="${disc.title}" c:_artist="${disc.artist}" />

如果我们依赖组件扫描和自动装配来创建和初始化组件的话,可以使用如下写法

public BlankDisc(@Value("${disc.title}") String title,@Value("${disc.artist}")String artist){...}

此外还需要配置PropertySourcesPlaceHolderConfigurer,如下:

@Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){ return new PropertySourcesPlaceholderConfigurer(); }

使用xml的时候配置如下:

<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beas" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:property-placeholder /> </beans>

2 使用spring表达式语言进行装配 1)SpEL的特性: 使用bean的ID来引用bean 调用方法和访问对象的属性 对值进行算术,关系和逻辑运算 正则表达式 集合操作

2)表示字面值 数字:#{3.14159} 科学记数法:#{9.87E4}//最终的值为98700 字符串:#{‘Hello’} 布尔类型:#{false}

3)引用bean属性和方法 引用bean:#{sgtPeppers} 引用属性:#{sgtpepepers.title} 引用方法: #{artistSelector.selectArtist()} #{artistSelector.selectArtist().toUpperCase()}//selectArtist()为空时,会抛出空指针异常 #{artistSelector.selectArtist()?.toUpperCase()}//selectArtist()为空时,将不会调用toUpperCase方法,返回null

4)在表达式中使用类型 #{T(java.lang.Math)} #{T(java.lang,Math).PI} #{T(java.lang,Math).random()}

5)SpEl运算符 运算符类型 运算符 ============================================ 算术运算符 +,-,*,/,%/^ 比较运算符 <,>,==,<=,>=,lt,gt,eq,le,ge 逻辑运算符 and,or,not 条件运算符 ?: (ternray), ?: (Elvis) 正则表达式 matches ===========================================

6)相关例子

#{2*T(java.lang.Math).PI*circle.radius^2} //计算圆的面积 #{disc.title + " by " +disc.artist} //拼接字符串 #{counter.total == 100} //判断是否相等,等同写法: #{counter.total eq 100} #{scorebord.score > 100?"winner":"loser"} //与三元运算符类似 #{disc.title ?: 'Rattle and Hum'} //表达式会判断disc.title是否为null,如果是null的话,那么表达式的结果将是:'Rattle and Hum' #{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'} //正则表达式,判断字符串是否有效的邮箱地址 #{jukebox.songs[4].title} //获取jukebox的songs集合中第五个元素的标题 #{jukebox.songs[T(java.lang.Math).random()*jukebox.songs.size()].title} //随机获取一首歌 #{'This is a tes'[3]} //获取字符串的第四个字符,即 s #{jukebox.songs.?[artist eq 'Aerosmith']} // .?[]用来对集合进行过滤,得到集合的子集,本例中为获取Aerosmith的所有歌曲 #{jukebox.songs.^[artist eq 'Aerosmith']} // 获取集合中第一个匹配项,即集合中第一次出现的Aerosmith的歌曲 #{jukebox.songs.$[artist eq 'Aerosmith']} // 获取集合中最后一个匹配项,即集合中最后一次出现的Aerosmith的歌曲 #{jukebox.songs.![title]} // 获取集合中所有歌曲的标题,将其投影到一个String类型的集合中 #{jukebox.songs.?[artist eq 'Aerosmith'].![title]}

最新回复(0)