spring EL 实现ref的效果
之前学习basic的时候有个疑问就是不知道如何实现bean中引用其他的bean的属性,当时是用ref来实现对其他bean的引用,但是ref必需引用的是一个常量。所以这种方式来实现对其他bean中的属性的引用是不合理的。
当我看到Spring Expression Language时发现原来我想实现的'ref'的效果就是使用Spring EL这种表达式就可以完成了。
而Spring EL有两种配置形式,一种是Spring EL 写在xml中,和zai xml定义bean一样,通过在定义bean的xml标签内使用"#{otherBean.property}" 或#{otherBean}的形式来完成。另一种是基于注解的方式。一下稍作说明:
第一种和第二种都是通过xml来加载spring context的但是xml里的内容不一样
第一种:直接在xml中定义spring 的上下文,并在bean中的属性字段直接使用SpringEL来引用其他bean或其他bean的属性
第二种: 在xml中定义Component的scan-package的包名,这样spring会在这个包中扫描并配置对应的bean,然后我们在对应的类中加上注解就可以了.
第一种:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="itemBean" class="com.ric.demo.Item">
<property name="name" value="itemA"/>
<property name="qty" value="10"/>
</bean>
<bean id="customerBean"
class="com.ric.demo.Customer">
<property name="item" value="#{itemBean}" />// 直接在这里使用Spring EL设置值
<property name="itemName" value="#{itemBean.name}"/>// 直接在这里使用Spring EL设置值
</bean>
</beans>
第二种
定义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: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:component-scan base-package="com.ric.demo" />
</beans>
配置对应的bean
@Component("customerBean")
public class Customer {
private Item item;
private String itemName;
@Override
public String toString() {
return "Customer{" +
"item=" + item +
", itemName='" + itemName + '\'' +
'}';
}
public Item getItem() {
return item;
}
// 使用Spring EL 来取到对应的value
@Value("#{itemBean}")
public void setItem(Item item) {
this.item = item;
}
public String getItemName() {
return itemName;
}
// 使用Spring EL 来取到对应的value
@Value("#{itemBean.name}")
public void setItemName(String itemName) {
this.itemName = itemName;
}
}
需要注意的是如果这里的 Spring EL里面引用的是其他的对象有一下这种效果
ApplicationContext context = new ClassPathXmlApplicationContext("BeansAutoScan.xml");
Item item = (Item)context.getBean("itemBean");
System.out.println(item);
Customer customer = (Customer)context.getBean("customerBean");
System.out.println(customer);
item.setName("geek");
System.out.println(item);
System.out.println(customer);
Item{name='item', qty=10}
Customer{item=Item{name='item', qty=10}, itemName='item'}
Item{name='geek', qty=10}
Customer{item=Item{name='geek', qty=10}, itemName='item'}
Process finished with exit code 0
也就是说如果引用的是item bean 我们的customer的itemBean属性的确是对item这个bean的一个引用。
但是Customer的itemName这个属性的值没有变,因为bean扫描的时候也是为上下文中的bean做一个初始化的工作,初始化完后item虽然对name做了一个更新的操作,但是customer的itemName的指针不会因为item的name做了变化而同步,而是依旧指向item原先name值的那个指针