SpringAction学习二、高级装配:运行时值注入

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/MASORL/article/details/82661677

到目前为止,注入的都是bean对象

但一个bean,往往还有其他的值,如String、int等,最简单的就是直接再构造方法上传值,但这样值就固定为name和titile了


    //为CDPlayer创建bean
    @Bean
    public MediaPlayer mediaPlayer(CompactDisc compactDisc){
        return new CDPlayer(compactDisc,"name", "title");
    }

如果想要再运行时,再决定值,可以使用注入外部值的方法,也可以使用spring提供的两种方法【属性占位符、SpEL表达式】

方式一:注入外部值

示例代码

接口1

package com.spring.chapter3.RuntimeValueInjection;

/**
 * 一个光盘接口
 */
public interface CompactDisc {
    void sing();//光盘的sing功能
}

接口1实现

package com.spring.chapter3.RuntimeValueInjection;

import org.springframework.stereotype.Component;

/**
 * CompactDisc实现类
 */
public class SgtPeppers implements CompactDisc {
    public void sing() {
        System.out.println("sgtPeppers的sing方法");
    }
}

接口2

package com.spring.chapter3.RuntimeValueInjection;

/**
 * 一个光盘接口
 */
public interface CompactDisc {
    void sing();//光盘的sing功能
}

接口2实现

package com.spring.chapter3.RuntimeValueInjection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

public class CDPlayer implements MediaPlayer {
    private CompactDisc compactDisc;
    private String name;
    private String title;

    public CDPlayer(CompactDisc compactDisc, String name, String title) {
        this.compactDisc = compactDisc;
        this.name = name;
        this.title = title;
    }

    @Override
    public String toString() {
        return "CDPlayer{" +
                "compactDisc=" + compactDisc +
                ", name='" + name + '\'' +
                ", title='" + title + '\'' +
                '}';
    }

    public void play() {
        System.out.println("播放器开始播放2");
        compactDisc.sing();
    }
}

属性源文件

disc.title = zzzzz
disc.name = abcd

配置文件

通过@PropertySource("classpath:app.properties")声明属性源

自动注入Environment, 通过其getProperty方法来获取属性源中的值

package com.spring.chapter3.RuntimeValueInjection;


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:app.properties")//声明属性源
public class JavaConfig {

    @Autowired
    Environment environment;

    @Bean
    public CompactDisc compactDisc(){
        return new SgtPeppers();
    }
    //为DCPlayer创建bean
    @Bean
    public MediaPlayer mediaPlayer(CompactDisc compactDisc){
        return new CDPlayer(compactDisc,
                environment.getProperty("disc.name"),
                environment.getProperty("disc.title"));
    }
}

测试

package com.spring.chapter3.RuntimeValueInjection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = JavaConfig.class)
public class RuntimeValueInjectionTest {
    @Autowired
    private CompactDisc compactDisc;

    @Autowired
    private MediaPlayer mediaPlayer;

    @Test
    public void profilesTest(){
        mediaPlayer.play();
        System.out.println(mediaPlayer.toString());

    }
}

结果:

播放器开始播放2
sgtPeppers的sing方法
CDPlayer{compactDisc=com.spring.chapter3.RuntimeValueInjection.SgtPeppers@225129c, name='abcd', title='zzzzz'}

方式二:使用属性占位符

属性占位符使用方式:${"xxxx"}

相关步骤:
(1)在构造器参数上使用@Value("${xxx}")来使用属性占位符注入值

示例代码

CDPlayer类:通过@Vlaue("${xxxx}")来获取到properties文件中的属性

package com.spring.chapter3.RuntimeValueInjection.PropertyPlaceholder;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc compactDisc;
    private String name;
    private String title;

    public CDPlayer(CompactDisc compactDisc, @Value("${disc.name}") String name,  @Value("${disc.title}")String title) {
        this.compactDisc = compactDisc;
        this.name = name;
        this.title = title;
    }

    @Override
    public String toString() {
        return "CDPlayer{" +
                "compactDisc=" + compactDisc +
                ", name='" + name + '\'' +
                ", title='" + title + '\'' +
                '}';
    }

    public void play() {
        System.out.println("播放器开始播放2");
        compactDisc.sing();
    }
}

配置类:

package com.spring.chapter3.RuntimeValueInjection.PropertyPlaceholder;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;

@Configuration
@ComponentScan
@PropertySource("classpath:app.properties")//声明属性源
public class JavaConfig {


    @Bean
    public CompactDisc compactDisc(){
        return new SgtPeppers();
    }

 

当然,也可以使用XML来使用占位符

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c"
       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 location="classpath:app.properties" />

    <bean id="sgtPeppers" class="com.spring.chapter3.RuntimeValueInjection.xmlproperties.SgtPeppers" />
    <bean id="cdPlayer" class="com.spring.chapter3.RuntimeValueInjection.xmlproperties.CDPlayer"
          c:_0-ref="sgtPeppers"
          c:_1="${disc.name}"
          c:_2="${disc.title}"
    />
</beans>

注:在《SpringAction》中,说必须要一个PropertySourcesPlaceholderConfigurer bean,但实际情况时,发现根本不需要,也能解析占位符。

方式三:通过SpEL表达式

根据书上的方式,${"systemProperties['disc.name']"} 并不能获取到值。

经过研究,发现了一种可行的方法

那就是通过environment的getProperty方法来获取到值。SpEL会以environment为bean id 查找对应的bean

package com.spring.chapter3.RuntimeValueInjection.spel;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc compactDisc;
    private String name;
    private String title;


    public CDPlayer(CompactDisc compactDisc,
                    @Value("#{environment.getProperty('disc.name')}") String name,
                    @Value("#{environment.getProperty('disc.name')}")String title) {
        this.compactDisc = compactDisc;
        this.name = name;
        this.title = title;
    }

    @Override
    public String toString() {
        return "CDPlayer{" +
                "compactDisc=" + compactDisc +
                ", name='" + name + '\'' +
                ", title='" + title + '\'' +
                '}';
    }

    public void play() {
        System.out.println("播放器开始播放3");
        compactDisc.sing();
    }
}

随后又试了xml中配置,发现结果为null!!!!

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c"
       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 location="classpath:app.properties" />

    <bean id="sgtPeppers" class="com.spring.chapter3.RuntimeValueInjection.spel.SgtPeppers" />
    <bean id="cdPlayer" class="com.spring.chapter3.RuntimeValueInjection.spel.CDPlayer"
          c:_0-ref="sgtPeppers"
          c:_1="#{environment.getProperty('disc.name')}"
          c:_2="#{environment.getProperty('disc.name')}"
    />
</beans>

所以!在spel上,还有很长的路要走

猜你喜欢

转载自blog.csdn.net/MASORL/article/details/82661677