第3章—高級裝配—運行時注入

運行時注入

當咱們常常用以下的硬解碼方式來配置文件:
<bean id="SgtPeppers" class="com.CDDemo.SgtPeppers" p:title="sgt" p:song="Twinkle, twinkle, little start">
        <property name="title" value="sgt"/>
        <property name="song" value="Twinkle, twinkle, little start"/>
    </bean>

但有時咱們須要避免硬解碼,須要想要這些值在運行時肯定,Spring提供了兩種在運行時求值的方式:java

  • 屬性佔位符
  • Spring表達式語言(SpEL)

1.注入外部的值

​ 在Spring中,處理外部值得最簡單方式就是申明屬性源並經過Spring的Enviroment來檢索屬性.例如:正則表達式

@Configuration
@PropertySource("classpath:app.properties")
public class ExpressionTest {
    @Autowired
    Environment environment;

    @Test
    public BlankDisc disc(){
        return new BlankDisc(

                environment.getProperty("disc.title"),
                environment.getProperty("disc.artist")
        );
    }
}

app.properties數據庫

disc.title="titeTest"
disc.artist="Twinkle, twinkle, little start"

2.深刻學習Spring的Environment

Environment的getProperty()方法有四個重載的變種形式:數組

  • String getProperty(String key)
  • String getProperty(String key,String defaultValue)
  • T getProperty(String key, Class<T> type)
  • T getProperty(String key, Class<T> type,T defaultValue)

前兩種形式的getProperty()方法都是返回String類型的值。後兩種重載方法不是直接返回字符串,而是將獲取到的值轉化爲指定類型的值,好比獲取鏈接池中維持鏈接的總數量:app

String disc = env.getProperty("disc.title","dukh");

除了屬性相關的功能外,Environment還提供了一些方法來檢查哪些profile處於激活狀態:dom

  • String [] getActiveProfiles():返回激活profile名稱的數組;
  • String [] getDefaultProfile():返回默認profile名稱的數組;
  • boolean acceptsPrifiles(String ... profiles):若是environment支持給定的profile返回true。

3.解析屬性佔位符

​ Spring一直支持將屬性定義到外部的屬性文件中,並使用佔位符值將其插入到Spring bean中.在Spring裝配中,佔位符的形式爲使用"${...}"包裝的屬性名稱.學習

好比咱們常見的使用數據庫鏈接池的方式:ui

<!-- 讀取db.properties文件. 讀取到數據庫信息 -->
	<context:property-placeholder location="classpath:db.properties"/>
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="driverClassName" value="${jdbc.driver}"></property>
		<property name="url" value="${jdbc.url}"></property>
		<property name="username" value="${jdbc.username}"></property>
		<property name="password" value="${jdbc.password}"></property>
	</bean>

​ 這裏須要注意的是使用Spring context命名空間的<context:property-placeholder location="classpath:db.properties"/>元素將爲你生成ProoertySourcesPlacehodlerConfigurer bean.url

4.SpEL樣例

SpEL的表達式是"#{...}"之中放入相應的計算或者方法調用等,以下所示:spa

@Value("#{T(System).currentTimeMillis()}") Long time

#{T(System).currentTimeMillis()}最終計算的是當前時間的毫秒值.T()表達式會將java.lang.System視爲java中對應的類型,所以能夠調用其Static修飾的currentTimeMillis()方法.

表示字面值

浮點:

#{3.14159}

科學計數法:98700

#{9.87E4}

String:

#{"Heloo"}

Boolean:

#{false}

引用bean,屬性和方法

將bean的ID做爲SpEL表達式:

#{SgtPeppers}

#{SgtPeppers.title}

#{SgtPeppers.play()}

還能夠防止是null的狀況 要先進行判斷:

#{SgtPeppers.play()?.toUpperCase()}

T()運算符的結果是一Class對象,它的真正價值在於它可以訪問目標類型的靜態方法和常量:

T(java.lang.Math).random()

5.SpEL運算符

SpEL提供了幾種運算符,這些運算符能夠用在SpEL表達式中的值上。

運算符類型 運算符
算術運算 +、-、*、/、%、^
關係運算 <、>、==、<=、>=、lt、gt、eq、le、ge
邏輯運算 and、or、not、|
條件運算 ?:(ternary)、?:(Elvis)
正則表達式 matches

數值運算

<!-- +運算符:兩個數字相加 -->
<property name="adjustedAmount" value="#{counter.total + 42}"/>
<!-- +運算符:用於鏈接字符串 -->
<property name="fullName" value="#{performer.firstName + ' ' + performer.lastName}"/>
<!-- -運算符:兩個數字相減 -->
<property name="adjustedAmount" value="#{counter.total - 20}"/>
<!-- *運算符:乘法運算 -->
<property name="circumference" value="#{2 * T(java.lang.Math).PI * circle.radius}"/>
<!-- /運算符:除法運算 -->
<property name="average" value="#{counter.total / counter.count}"/>
<!-- %運算符:求餘運算 -->
<property name="remainder" value="#{counter.total % counter.count}"/>
<!-- ^運算符:乘方運算 -->
<property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}"/>

比較值

比較兩個值是否相等,可使用」==」運算符:

<!-- 假設equal屬性爲布爾屬性 -->
<property name="equal" value="#{counter.total == 100}"/>

邏輯表達式

運算符 操做
and 邏輯AND運算操做,只有運算符兩邊都是true,表達式才能是true
or 邏輯OR運算操做,只要運算符的任意一邊是true,表達式就會是true
not或! 邏輯NOT運算操做,對運算結果求反
<!-- and 運算符 -->
<property name="largeCircle" value="#{shape.kind == 'circle' and shape.perimeter gt 10000}"/>
<!-- ! 運算符 -->
<property name="outOfStock" value="#{!product.availiable}"/>
<!-- not 運算符 -->
<property name="outOfStock" value="#{not product.availiable}"/>

條件表達式

<!-- ?:三元運算符 -->
<property name="song" value="#{kenny.song != null ? kenny.song : 'Greensleeves'}"/>

正則表達式

<!-- 判斷一個字符串是不是有效的郵件地址 -->
<property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9.-%+-]+@[a-zA-Z0-9.-]+\\.com'}"/>
相關文章
相關標籤/搜索