Java 19:Spring 2(Bean运行时值注入:占位符和SpEL表达式 )

来源:互联网 发布:手机网络看不了视频 编辑:程序博客网 时间:2024/06/04 19:34

前面一节讲Bean的配置,篇幅太长,其实还有不少东西没有加进去,比如Bean冲突,Bean作用域,Bean在不同环境下的加载,不过那些高级特性用的机会不多,就不写了。前面学习的时候,就提到,我们初始化的Bean都是硬编码的,Bean的装配除了确定Bean之间的依赖关系,将一个Bean的引用注入到另一个Bean中的属性和构造器中,将值诸如属性或构造函数也是重要的一部分。

Spring提供两种运行时求值的方式:

1、属性占位符

2、Spring表达式SpEL


属性占位符

首先是最简单的用Environment检索属性值。我们首先创建一个app.properties文件,位置就放到src下面

officeNo="office.number"brand="app.brand"price=1111111.1  //声明了上一节car和office的字段
思想很简单,读取文件获取Bean的初始化信息
加入了Environment的Java配置文件:

@Configuration@PropertySource("classpath:/app.properties")public class BossConfig {@AutowiredEnvironment env;@Beanpublic Boss boss(){return new Boss();}@Beanpublic Car car(){return new Car(env.getProperty("brand"),Double.parseDouble(env.getProperty("price")));}@Beanpublic Office office(){return new Office(env.getProperty("officeNo"));}}
这样就可以在运行时通过读取外部文件,诸如各个域的值。

Environment有获取property的重载函数和其他一些函数,对属性的完备性、默认值进行设置,不过也没有什么难的东西,就不说了。直接从Environment检索属性是比较简单的,尤其是Java配置bean的时候。

占位符

Spring支持将属性定义在外部文件中,并使用占位符将其插入到Spring Bean中,占位符的形式为 ${......} 包装属性的名称(和Web MVC里形式很像啊)。

占位符按我的理解,重点在于信息的集中配置管理一些信息,比如数据库的连接信息等,至于创建类的作用上,读取文件有点迟钝呀。

为了使用占位符,必须使用PropertyPlaceholderConfigurer或者PropertySourcesPlaceholderConfigurer,建议使用后者(名词太长我都不想打了)。因为要声明成Bean,所以也就涉及了前面说到的几种方法。下面还是用到Office、Car两个类,我分别用组件扫描和显式声明来使用占位符。

下面是完整代码:

Boss.java:

@Componentpublic class Boss {    //简化一点,没有对Boss有任何处理@Autowiredprivate Car car;@Autowiredprivate Office office;public String toString(){return "car:"+car+"  office:"+office;}}
Car.java:
public class Car {private String brand;private Double price;public Car(String brand,Double price)   //构造函数,在配置文件里,显式构造Bean用到{this.brand=brand;this.price=price;}public String toString(){return brand+" "+price;}}
Office.java:

@Component    //使用组件扫描public class Office {private String officeNo;public Office(@Value("${officeNo}")String a){   //a被占位符替代,并根据properties文件里的值初始化this.officeNo=a;}public String toString(){return officeNo;}}
BossConfig:

@Configuration@ComponentScanpublic class BossConfig {@Beanpublic Car car(@Value("${brand}")String brand,@Value("${price}")String price){ //用法和构造函数类似return new Car(brand,Double.parseDouble(price));}@Beanpublic static PropertySourcesPlaceholderConfigurer placeholder(){PropertySourcesPlaceholderConfigurer a=new PropertySourcesPlaceholderConfigurer();a.setLocation(new FileSystemResource("I:\\JavaWorkSpace2\\SpringLearing\\src\\app.properties"));//文件路径return a;}}

最后,直接用 new AnnotationConfigApplicationContext(BossConfig.class);   加载配置文件,就可以将4个Bean全都注册,并且Office、Car采用app.properties的值初始化了。

XML占位符:

Boss、Car、Office都是普通的POJO(用到<property>需要getter、setter,用到<constructor>需要构造函数)

xml文件:

   <bean id="propertyConfigurer"  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">        <property name="location">            <value>classpath:/app.properties</value>        </property>   </bean>         <bean id="boss" class="com.baobaotao.Boss">    <property name="car" ref="car"></property><property name="office" ref="office"></property>    </bean>                <bean id="car" class="com.baobaotao.Car">             <constructor-arg  value="${brand}"/>             <constructor-arg  value="${price}"/>         </bean>           <bean id="office" class="com.baobaotao.Office">             <property name="officeNo"  value="${officeNo}"/>         </bean>   

SpEL表达式:

表达式会在运行时计算得到值,形式是"#{}"
使用Bean的id来引用Bean
<property name="car" value="#{car}"/> 
就相当于前面的:
<property name="car" ref="car"/>  

引用其他Bean的属性:
<constructor-arg  value="#{office.officeNo}"/> 

调用Bean的方法:
<constructor-arg  value="#{office.aa()}"/>
引用外部类(非Bean类)的方法或变量,使用T():
 <constructor-arg  value="#{T(com.baobaotao.test).aa}"/> 

用EL表达式设置初值,进行依赖关系设置:
public class Boss {@Value("#{car}")   //代替@Autowiredprivate Car car;@Value("#{office}")private Office office;  @Value("asd")     //基本类型直接初始化private String asd;
在Java类中也可以动态赋值:
@Value("#{T(com.baobaotao.test).getString()}")private String asd;

El表达式也可以支持三元运算符:? 甚至计算正则表达式、计算集合、过滤等,这里就不详细说了。








阅读全文
0 0
原创粉丝点击