1.声明Bean
Spring框架自带了10个命名空间。
1.aop为声明切面和将@AspectJ注解的类代理为spring切面提供了配置元素。
2.beans:支持声明Bean和转配Bean,是Spring最核心也是最原始的命名空间。
3.context:为spring应用上下文提供了配置元素,包括自动检测和自动转配Bean,注入非spring管理的对象。
4.jee:提供了与java ee API的集成,例如JNDI和EJB
5.jms:为声明消息驱动的POJO提供了配置元素
6.lang:支持配置有Groovy、JRuby等脚本实现的Bean
7.mvc:启动spring mvc的能力。
8.oxm:支持spring的对象到XML映射配置
9.tx:提供声明式事务配置
10.util:提供各种各样的工具类元素,包括把集合配置为Bean,支持属性占位符元素。
spring默认是通过默认构造方法的方式注入Bean的,可以使用<constructor-arg value=""/>来调用一个参数为值的构造器,也可以使用<constructor-arg ref="'/>来调用一个参数为对象的构造器,也可以按顺序使用多个<constructor-arg >来调用有多个参数的构造器。
有时候静态工厂方法是实例化对象的唯一方法。通过<bean>中factory-method属性来装配工厂创建的Bean。它允许调用一个指定的静态方法,代替构造方法来创建类的实例。
1.1 Bean的作用域
所以Spring Bean默认是单例的,就是分配Bean时总是同一个Bean。可以通过<bean>属性scope来指定作用域。
1.singleton:在每一个spring容器中,一个Bean的定义只有一个对象实例(默认)。
2.prototype:允许Bean的定义被实例化任意次(每次调用都创建一个实例)
3.request:在一次http请求中,每个Bean定义一个实例。仅基于web的spring上下文(例如spring mvc)有效
4.session:在一个http session中,每个Bean定义一个实例。仅基于web的spring上下文(例如spring mvc)有效
5.global-session:在一个全局http session中,每个Bean定义一个实例。仅在portlet上下文有效
<bean>中有init-method和destory-method属性来指定在Bean初始化和销毁时调用的方法。Bean实现InitlizingBean和DisposableBean也可是实现初始化和销毁,这样做的最大好处就是Spring能够自动检测实现类这些接口的bean,缺点是让bean和spring的API产生了耦合。推荐使用init-method和destory-method属性。
如果所有的Bean都有同一个初始化和销毁方法,可以再beans元素中加入default-init-method和default-destory-method属性。
2.注入Bean的属性
通常javaBean的属性是私有的,而且有set和get方法,spring借助属性的set方法配置属性的值,以实现setter方式的注入。
2.1注入简单值
通过<property>来注入,和<constructor-arg>类似,只不过一个通过构造器来注入值,一个通过属性的setter方法注入值。
<bean id="" class="">
<property name="属性" value="35"/>
<property name="name" value="jack"/>
</bean>
2.2引入其他Bean
<bean>
<property name="" ref="其他bean的id"/>
</bean>
还可以注入内部Bean。内部Bean就是定义在其他Bean内部的Bean。
<bean>
<property name="'>
<bean class=""/>
</property>
</bean>
<bean>
<constructpr-arg >
<bean class=""/>
</constructor-arg>
</bean>
内部Bean没有id属性,因为id属性没有必要,不会通过id来引用内部Bean,这也突出了内部Bean的最大缺点:不能复用。内部Bean仅适用于一次注入,而且不能被其他Bean引用。
2.3使用命名空间p来装配Bean的属性
<bean id="" class="" p:name="" p:age="" p:A-ref=""/>
p:xxx来指定属性。-ref标识表示装配的是引用而不是值。和<property>是等价的。
2.4装配集合
1.<list>:装配list类型的值,元素允许重复。
2.<set>:装配set类型的值,元素不允许重复
3.<map>:装配map类型的值,名称和值可以是任意类型。
4.<props>:装配properties类型的值:名称和值都是string类型。
2.4.1 list和set
<bean>
<property name="">
<list>
<ref bean=""/>
<ref bean=""/>
<ref bean=""/>
</list>
</property>
<property name="">
<set>
<value></value>
<value></value>
</set>
</property>
</bean>
list和set都可以用来装配类型为Collection的任意实现或数组的属性。意思就是如果属性为List list,可以用set来装配。
2.4.2装配集合
<property name="">
<map>
<entry key="" value=""/>
<entry key="" value-ref=""/>
<entry key-ref="" value=""/>
<entry key-ref="" value-ref=""/>
</map>
</property>
key:指定map中entry中的键
value:指定map中entry中的值
key-ref:指定map中entry的键为上下文中其他Bean的引用。
value-ref:指定map中entry的值为上下文中其他Bean的引用。
<property name="">//键值都为string时使用,也可以使用map
<props>
<prop key=""></prop>
<prop key=""></prop>
<prop key=""></prop>
</props>
</property>
<property>:用来给Bean的属性注入值或者引用
<props>:用来定义一个properties类型的集合值
<prop>:用来定义一个<props>中的成员。
2.5装配空值
spring可以把属性设置为null值。
<property name="" ><null/></property>
可能某个属性要设置为null值,或者覆盖自动装配的值就可以用这种方式。
3.使用表达式装配
上面讲的方式是静态的。要使用动态的方式可以使用Spring表达式语言(SpEL),它通过运行期的表达式将值或引用传递到Bean的属性或构造器中。
字面值:
<bean>
<property name="" value="#{23}"/>
<property name="" value="name is #{23}"/>
<property name="" value="#{1e4}"/>//10000.0
<property name="" value="#{'jack'}"/>//string类型的值
</bean>
引用Bean、properties和方法:SpEL可以通过id来引用其他的Bean
<property name="" value="#{abc}"/>//引用Bean
<property name="" value="#{abc.name}"/>//引用Bean中的属性
<property name="" value="#{abc.getA()}"/>//引用Bean中方法返回的值
<property name="" value="#{abc.getA().toUpperCase()}"/>//引用Bean中方法返回的值,大写,不能返回null,会报空指针异常
<property name="" value="#{abc.getA()?.toUpperCase()}"/>//引用Bean中方法返回的值,大写,?左边为null,什么都不做,不是null执行?后面的操作
操作类:T{}会调用类作用域的方法和常量。可以访问类的静态方法和常量
<property name="" value="#{T{java.lang.Math}.PI}"/>
<property name="" value="#{T{java.lang.Math}.random()}"/>
<property name="" value="#{T{java.lang.Math}.PI*100}"/>
<property name="" value="#{abc.age + 10}"/>
<property name="" value="#{abc.age +' ' +abc.name}"/>
<property name="" value="#{abc.age == 18}"/>
<property name="" value="#{abc.age <= 18}"/>
正则表达式:匹配返回true,否则false
<property name="" value="#{abc.email matches '[xxxxx]'}"/>
操作集合:
使用<util:list>配置一个集合。
<util:list id="aaa">
<bean class="" p:xxx="" p:xxx-ref=""/>
</util:list>
访问集合元素:
<property name="" value="#{aaa[2]}"/>
<util-properties id="bbb" location="classpath:bbb.properties" />
查询集合成员:
<property name="" value="#{aaa.?[age ==18]}"/>
.?返回的是[]中为true的集合,.^[]和.$[]返回的是第一和最后匹配项。
不要多过使用这些表达式