Spring(四)---高级装配(2)

(四)运行时值的注入
(1)注入外部的值
在Spring中,处理外部值的最简单的方式就是声明属性源并通过Spring的Environment来检索属性
这里写图片描述
—->深入了解Spring的Environment
getProperty()的四个重载的形式:
这里写图片描述

//getProperty(string key)
Enviroment env;
env.getProperty(disc.title);
//getProperty(string key,String defaultValue) --若Key不存在时,可以设定一个默认值
env.getProperty(disc.title,test);
//env.getProperty(String key,Class<T> type) --可以将key所对应的value值自动转换类型
int count = env.getProperty(db.connection.count,Integer.class);

方法 描述
getRequriedProperty() 希望该属性必须要定义,若没有定义抛异常
containsProperty() 检查某个属性是否存在
getPropertyAsClass 将该属性解析为类
String[] getActiveProfiles() 返回激活profile名称的数组
String[] getDefaultProfiles() 返回默认profile名称的数组
boolean acceptProfiles(String profile) 如果enviroment支持给定的profile的话,就返回true

(2)解析属性占位符
Spring一直支持将属性定义到外部的属性文件中,并使用占位符将其插入到Spring bean中.在Spring装配中,占位符的形式为使用”${…}”包装属性名称
例:

//在XML中
<!-- 引入外部资源文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
   <property name="user" value="${jdbc.user}"></property>
   <property name="password" value="${jdbc.password}"></property>
   <property name="driverClass" value="${jdbc.driverClass}"></property>
   <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
</bean>
//组件扫描和自动装配来创建和初始化应用组件,使用@Value注解
//为了使用占位符,必须要配置一个PerpertyPlaceholderConfigurer bean或PerpertySourcesPlaceholderConfigurer bean(推荐使用:能够基于Spring Environment及其属性源来解析占位符)


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

在java配置文件配置PerpertySourcesPlaceholderConfigurer
这里写图片描述
(3)使用Spring表达式语言进行装配
Spring3引入了Spring表达式语言(Spring Expression Language,SpEL),它能够以强大和简洁的方式将值装配到bean的属性和构造器参数中
SpEL拥有很多特性:

  • 使用bean的ID来引用bean;
  • 调用方法和访问对象的属性;
  • 对值进行算术,关系和逻辑;
  • 正则表达式匹配
  • 集合操作
    (1)标识字面值
    SpEL可以用来表示整数字面值,浮点数,String值以及Boolean值
    例 #{3.14159}
    (2)引入bean,属性和方法
    SpEL可以通过ID引用其他的bean,例如可以使用SpEL将一个bean装配到另外一个bean的属性中
    例:
//引入bean的属性
#{testClass.name}
//引入bean的方法
#{testClass.getName()}
//对于调用方法的返回值来说,我们可以调用它的方法,若调用的方法可能为Null的话,可能会造成空指针异常,为了避免空指针异常,可以使用?.作用是若调用的方法为null,则不执行后面的方法
#{testClass.getName()?.toUpperCase()}

(3)使用静态方法
如果要在SpEL中访问静态方法或常量的话,要使用T()运算符
例:
T(java.lang.Math).PI
(4)SpEL运算符
这里写图片描述
这里写图片描述
(5)计算正则表达式
SpEl通过matches运算符支持表达式中的模糊匹配,matches会返回一个boolean值,匹配返回true,否则返回false
例判断字符串是否是一个邮箱
这里写图片描述
(6)计算集合
SpEL可以进行集合和数组的操作;

//"[]"运算符用来从集合或数组中按照索引获取元素
//例1 计算songs集合中第五个(基于零开始)元素的title属性
#{jukebox.songs[4].title}
//例2 可以从String中获取一个字符串
#{'This is a test'[3]}   ---> 's'

//SpEL还提供了查询运算符(.?[]),它会用来对集合进行过滤,得到集合的一个子集
//例3 想得到jukbox中artist属性为Aerosmith的所有歌曲
#{jukebox.songs.?[artist eq 'Aerosmith']}

//".^[]和.$[]"分别用来在集合中查询第一个匹配项和最后一个匹配项
//例4 查找列表中第一个artist属性为Aerosmith的歌曲
#{jukebox.songs.^[artist eq 'Aerosmith']}

//投影查询运算符(.![])
//例5 假设不想要歌曲对象的集合,而是所有歌曲名称的集合
#{jukebox.songs.![title]}
//例6 获得Aerosmith所有歌曲的名称列表
#{jukebox.songs.?[artist eq 'Aerosmith'].![title]}

(五)内部bean

  • 当Bean实例仅仅给一个特定的属性使用时,可以将其声明为内部Bean.内部Bean声明直接包含在<property><constructor-arg>元素里,不需要设置任何id或name属性;
  • 内部Bean不能使用在任何其他地方
    <!-- 声明使用内部 bean -->
    <bean id="service2" class="com.atguigu.spring.ref.Service">
        <property name="dao">
            <!-- 内部 bean, 类似于匿名内部类对象. 不能被外部的 bean 来引用, 也没有必要设置 id 属性 -->
            <bean class="com.atguigu.spring.ref.Dao">
                <property name="dataSource" value="c3p0"></property>
            </bean>
        </property>
    </bean>

(六)继承Bean配置
- Spring 允许继承 bean 的配置, 被继承的 bean 称为父 bean. 继承这个父 Bean 的 Bean 称为子 Bean;
- 子 Bean 从父 Bean 中继承配置, 包括 Bean 的属性配置;
- 子 Bean 也可以覆盖从父 Bean 继承过来的配置;
- 父 Bean 可以作为配置模板, 也可以作为 Bean 实例. 若只想把父 Bean 作为模板, 可以设置 <bean>的abstract 属性为 true, 这样 Spring 将不会实例化这个 Bean;
- 并不是 <bean> 元素里的所有属性都会被继承. 比如: autowire, abstract 等;
- 也可以忽略父 Bean 的 class 属性, 让子 Bean 指定自己的类, 而共享相同的属性配置. 但此时 abstract 必须设为 true

<bean id="user4" parent="user" p:userName="Bob"></bean>

(七)依赖Bean的配置
- Spring 允许用户通过 depends-on 属性设定 Bean 前置依赖的Bean,前置依赖的 Bean 会在本 Bean实例化之前创建好;
- 如果前置依赖于多个 Bean,则可以通过逗号,空格或的方式配置 Bean 的名称

<bean id="user5" parent="user" p:userName="Backham" depends-on="user6"></bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章