美文网首页
Spring 学习笔记(五)运行时注入

Spring 学习笔记(五)运行时注入

作者: Theodore的技术站 | 来源:发表于2018-12-16 19:09 被阅读0次

    直接看代码示例:

    @Bean
    public CompactDisc sgtPeppers(){
        return new BlankDisc("Sgt. Pepper's Lonely Hearts Club Bans","The Beatles");
    }
    

    这里的 tittle artist 都是硬编码的,但有的时候,我们可能会希望避免硬编码值,而是想让这些值在运行时再确定。为了实现这些功能,Spring提供了两种在运行时求值的方式:
    -属性占位符(Property placeholder)。
    -Spring表达式语言(SpEL)。

    注入外部的值

    //程序清单3.7 使用@PropertySource 注解和Environment
    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
        
        @Bean
        public BlankDisc disc(){
            return new BlankDisc(env.getProperty("disc.title"),env.getProperty("disc.artist");
        }
    }
    

    在本例中,@PropertySource引用了类路径中一个名为app.properties的文件。定义了 title 和 artist,这个属性会加载到 spring 的 Environment 中,稍后可以从这里检索属性。同时,在disc()方法中,会创建一个新的BlankDisc,它的构造器参数是从属性文件中获取的,而这是通过调用getProperty()实现的。
    getProperty()方法并不是获取属性值的唯一方法,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)
    

    Environment还提供了几个与属性相关的方法,如果你在使用getProperty()方法的时候没有指定默认值,并且这个属性没有定义的话,获取到的值是null。如果你希望这个属性必须要定义,那么可以使用getRequiredProperty()方法,如下所示:

    @Bean
    public BlankDisc disc(){
        return new BlankDisc(env.getRequireProperty("disc.tltle"),
                             env.getRequireProperty("disc.artist"));
    }
    

    在这里,如果disc.title或disc.artist属性没有定义的话,将会抛出IllegalStateException异常。
    如果想检查一下某个属性是否存在的话,那么可以调用Environment的containsProperty()方法:

    boolean titleExists = env.containsProperty{"disc.title"};
    

    最后,如果想将属性解析为类的话,可以使用getPropertyAsClass()方法:

    Class<CompactDisc> cdClass = enc.getPropertyAsClass("disc.class",CompactDisc.class);
    

    除了属性相关的功能以外,Environment还提供了一些方法来检查哪些profile处于激活状态:
    -String[] getActiveProfiles():返回激活profile名称的数组;
    -String[] getDefaultProfiles():返回默认profile名称的数组;
    -boolean acceptsProfiles(String... profiles):如果environment支持给定profile的话,就返回true。

    属性占位符

    Spring一直支持将属性定义到外部的属性的文件中,并使用占位符值将其插入到Spring bean中。在Spring装配中,占位符的形式为使用“${.. }”包装的属性名称。作为样例,我们可以在XML中按照如下的方式解析BlankDisc构造器参数:

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

    如果我们依赖于组件扫描和自动装配来创建和初始化应用组件的话,那么就没有指定占位符的配置文件或类了。在这种情况下,我们可以使用@Value注解,它的使用方式与@Autowired注解非常相似。比如,在BlankDisc类中,构造器可以改成如下所示:

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

    为了使用占位符,我们必须要配置一个PropertyPlaceholderConfigurer bean或PropertySourcesPlaceholderConfigurer bean。从Spring3.1开始,推荐使用PropertySourcesPlaceholderConfigurer,因为它能够基于Spring Environment及其属性源来解析占位符。如下的@Bean方法在Java中配置了PropertySourcesPlaceholderConfigurer:

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

    如果你想使用XML配置的话,Spring context命名空间中的<context:propertyplaceholder>元素将会为你生成PropertySourcesPlaceholderConfigurer bean

    使用Spring表达式语言进行装配

    Spring 3引入了Spring表达式语言(Spring Expression Language,SpEL)SpEL拥有很多特性,包括:
    -使用bean的ID来引用bean;
    -调用方法和访问对象的属性;
    -对值进行算术、关系和逻辑运算;
    -正则表达式匹配;
    -集合操作。

    SpEL 样例
    SpEL 表达式要放在 “#{ ... }” 之中。

    表示字面量

    #{3.14159}  //浮点数
    #{9.87E4}  //科学技术法
    #{'Hello'}  //String
    #{false}   //布尔值
    

    引用 bean、属性和方法。

    #{sgtPeppers}  //引用 bean
    #{sgtPeppers.artist}  //引用 bean 的一个属性
    #{artistSelect.selectArtist()}  //调用方法
    #{artistSelect.selectArtist().toUpperCase()}  //改为大写字母
    

    在表达式中使用类型

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

    SpEL 运算符


    image.png
    image.png
    #{2 * T(java.lang.Math).PI * circle.radius}
    #{scoreboard.score > 1000 ? "Winner!" : "Loser"}
    

    计算正则表达式

    #{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}
    

    计算集合

    #{jukebow.songs[4].title}
    #{'This is a test'[3]}  //表示 string 中第四个
    //SpEL 提供了查询运算符 (.?[])
    #{jukebox.songs.?[artist eq 'Aerosmith']}
    //SpEL 还提供了 (.^[]) (.$[]) 分别用来在集合中查找第一个和最后一个匹配项
    #{jukebox.songs.^[artist eq 'Aerosmith']}
    //SpEl 提供了投影运算符 (.![]) 从集合中选择特定的属性放到另一个集合中
    #{jukebox.songs.![title]}
    

    相关文章

      网友评论

          本文标题:Spring 学习笔记(五)运行时注入

          本文链接:https://www.haomeiwen.com/subject/ysmwhqtx.html