普通装配方式
声明Bean
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(int age) {
this.age = age;
}
public void sayAge(){
System.out.println("age->" + age);
}
}
通过构造器注入
在 springTest.xml 中配置:
<bean id="duke" class="类的完全限定名">
<constructor-arg value="15">
<!--如果需要传入引用对象-->
<constructor-arg ref="引用对象在xml中的id"
</bean>
main 方法中配置:
ApplicationContext ctx = new ClassPathXmlApplicationContext("springTest.xml");
User user = (User) ctx.getBean("tom");
user.sayAge();
Bean的作用域
如果我们需要让Spring在每次请求时都为Bean产生一个新实例,需要配置Bean的scope
<bean id="ticket" class="..." scope="prototype" />
Spring还提供了其他几个作用域选项:
- singleton: 在每一个Spring容器中,一个Bean定义只有一个对象示例(默认)
- prototype: 允许Bean的定义可以被实例化任意次(每次调用都创建一个示例)
- request: 在一次HTTP请求中,每个Bean定义对应一个实例,该作用域仅在基于Web的Spring上下文(例如Spring MVC)中才有效
- session: 在一次HTTP Session中,每个Bean定义对应一个实例,该作用域仅在基于Web的Spring上下文(例如Spring MVC)中才有效
- global-session: 在一个全局HTTP Session中,每个Bean定义对应一个实例,该作用域仅在基于Web的Spring上下文(例如Spring MVC)中才有效
初始化和销毁Bean
<bean id="..." class="..."
init-method="初始化后方法名"
destory-method="销毁前调用的方法"
/>
还可以配置默认的init-method和destory-method:
<?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">
default-init-method="默认初始化方法"
default-default-method="默认销毁前调用的方法"
</beans>
注入Bean属性
Bean的声明:
public class User {
private String name;
private int age;
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(int age) {
this.age = age;
}
public void sayAge(){
System.out.println("age->" + age);
}
public void sayName() {
System.out.println("name->" + name);
}
}
xml中的配置:
<bean id="jack" class="User">
<constructor-arg value="19"/>
<property name="name" value="Jack" />
<!--如果需要引用其他对象-->
<property name="..." ref="..." />
</bean>
使用Spring的命名空间p装配属性
在xml的根标签beans加上以下声明:
xmlns:p="http://www.springframework.org/schema/p"
使用方式:
<bean id="jack" class="User"
p:name = "Jack"
<!--如果需要属性为引用对象-->
p:poem-ref = "poem"
/>
装配集合
Java中共有4中数据集合,分别是:
- List: 装配list类型的值,允许重复
- Set: 装配set类型的值,不允许重复
- Map: 装配map类型的值,名称和值可以是任意类型
- pros: 装配properties类型的值,名称和值必须是String类型
以下是装配 List,Set,Array 的例子
<bean id="libai" class="User">
<property name="poems">
<list>
<ref bean="tangshi" />
<ref bean="songci" />
<ref bean="yuanqu" />
</list>
</property>
</bean>
以下是装配 Map 的例子
<bean id="libai" class="User">
<property name="poems">
<map>
<entry key="tangshi" value-ref="tangshi" />
<entry key="songci" value-ref="songci" />
<entry key="yuanqu" value-ref="yuanqu"/>
</map>
</property>
</bean>
以下是装配 properties 的例子
<bean id="libai" class="User">
<property name="poems">
<props>
<prop key="tangshi">唐诗三百首</prop>
<prop key="songci">宋词五百首</prop>
<prop key="yuanqu">元曲一千首</prop>
</props>
</property>
<!--设定某属性为空-->
<property name="someThingNull"><null/></property>
</bean>
使用SpEL表达式装配
字面值
<!--整形-->
<property name="count" value="#{5}" />
<!--混用-->
<property name="message" value="This count is #{5}"/>
<!--浮点型-->
<property name="floatNum" value="#{89.7}"/>
<!--科学计数法-->
<property name="longNum" value="#{1e4}"/>
<!--字符串-->
<property name="str" value="#{'String'}"/>
<!--布尔型-->
<property name="enabled" value="#{false}"/>
引用Bean,properties和方法
<!--引用Bean-->
<property name="BeanID" value="#{Bean}"/>
<!--等同于-->
<property name="BeanID" ref="Bean"/>
<!--引用方法-->
<property name="song" value="#{songSelector.selectSong()}"/>
<!--将返回值全部转换为大写-->
<property name="song" value="#{songSelector.selectSong().toUpperCase()}"/>
<!--避免NullPointerException异常-->
<property name="song" value="#{songSelector.selectSong()?.toUpperCase}"/>
操作类
在SpEL中,使用 T() 运算符会调用类的作用域的方法和常量
<!--调用常量-->
<property name="PI" value="#{T(java.lang.Math).PI}"/>
<!--调用方法-->
<property name="randomNum" value="#{T(java.lang.Math).random()}"/>
在SpEL上执行操作
<property name="arithmetic" value="#{counter.total + 43}"/>
<property name="arithmetic" value="#{counter.total - 43}"/>
<property name="arithmetic" value="#{2 * T(java.lang.Math).PI}"/>
<property name="arithmetic" value="#{counter.total / counter.count}"/>
<property name="arithmetic" value="#{counter.total % 20}"/>
<!--SpEL还提供了平方运算-->
<property name="arithmetic" value="#{T(java.lang.Math).PI ^ 2}"/>
<!--执行字符串链接-->
<property name="str" value="user.firstName + ' ' + user.lastName"/>
<!--比较值-->
<property name="equal" value="#{counter.total == 1000}"/>
<!--大于等于和小于等于在XML中有特殊含义,SpEL表达式提供了语义化的表达式-->
<!--小于等于-->
<property name="equal" value="#{counter.total le 1000}"/>
<!--大于等于-->
<property name="equal" value="#{counter.total ge 1000}"/>
逻辑表达式
- and
- or
- not或!
条件表达式
与Java中的三目运算符相同
正则表达式
运算符号 : matches
访问集合成员
<!--提取集合中的元素-->
<property name="city" value="#{cities[2]}"/>
<!--随机提取元素-->
<property name="city" value="#{cities[T(java.lang.Math).randow() * cities.size()]}"/>
<!--获取Map中的成员-->
<property name="city" value="#{cities['beijing']}"/>
筛选集合成员
<!--筛选人数大于等于10万的城市集合-->
<property name="bigCities" value="#{cities.?[population gt 100000]}"/>
<!--筛选第一个符合条件的集合-->
<property name="bigCities" value="#{cities.^[population gt 100000]}"/>
<!--筛选最后一个符合条件的集合-->
<property name="bigCities" value="#{cities.$[population gt 100000]}"/>
投影集合
集合投影是从集合的每一个成员中选择特定的属性放入一个新的集合中。
例如我们仅仅需要包含城市名称的一个String类型集合,而不是City对象集合,就需要如下操作
<property name="cityName" value="#{cities.![name]}"/>
如果需要得到城市名字和国家名称的集合,比如返回"Beijing,China","NewYork,America"这样的结果
<property name="cityName" value="#{cities.![name + ',' + state]}"/>