code From Spring In Action(Bean and Dependency Injection)

1.典型的Spring配置文件

<?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-2.5.xsd">
</beans>

2.Spring beans 配置

<bean id="user" class="com.zbwang.demo.User"/>

<bean id="user" class="com.zbwang.demo.User">
    <constructor-arg value="10"/>
</bean>

<bean id="user" class="com.zbwang.demo.User">
    <constructor-arg value="10"/>
    <constructor-arg ref="sonnet"/>
</bean>

<bean id="stage" class="com.zbwang.demo.Stage" factory-method="getInstance"/>

<bean id="user" class="com.zbwang.demo.User" scope="prototype"/>

<bean id="user" class="com.zbwang.demo.User" init-method="turnOn" destroy-method="turnOff"/>

InitializingBean声明了afterPropertiesSet方法作为初始化方法,而DisposableBean声明了destroy方法,使用这些接口的缺点是Bean和Spring的API产生了耦合,除非开发一个明显在Spring容器中使用的Bean. 可以为所有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-2.5.xsd"
    default-init-method="turnOn"
    default-destroy-method="turnOff">
</beans>

 

set注入

<bean id="user" class="com.zbwang.demo.User">
    <property name="username" value="focusahaha"/>
    <property name="age" value="20"/>
  <property name="neigbor" ref="melon"/>
</bean>

内部Bean

<bean id="user" class="com.zbwang.demo.User">
    <property name="date">
        <bean class="com.zbwang.demo.Date"/>
    </property>    
</bean>

P命名空间

<?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:p="http://www.springframework.org/schema/p" 
           xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="user" class="com.zbwang.demo.User" 
    p:username = "focusahaha"
    p:age = "20"
  p:neigbor-ref = "melon"/>
</beans>

 bean 集合注入

<bean id="user" class="com.zbwang.demo.User">
    <property name="friends">
        <list>
            <ref bean="lilei"/>
            <ref bean="hanmeimei"/>
            <value>something</value>
        </list>
    </property>
    <property name="favourite">
        <map>
            <entry key="guitar" value-ref="guitar"/>
            <entry key="cymbal" value-ref="cymbal"/>
        </map>
    </property>    
    <property name="instruments">
        <props>
            <prop key="guitar">guitar</prop>
            <prop key="cymbal">cymbal</prop>
        </props>
    </property>
    <property name="money">
        <null/>
    </property>
</bean>

Spring 3 引入了Spring表达式语言SPEL,通过运行期执行的表达式将值装配到bean的属性或者构造函数中。

1.使用#{}会提示Spring这个标记中的内容为SPEL表达式

<bean id="user" class="com.zbwang.demo.User">
    <property name="content1" value="#{5}"/>
    <property name="content2" value="The value is #{5}"/>
    <property name="content3" value="#{'chuck'}"/>
    <property name="content4" value='#{"chuck"}'/>
    <property name="content5" value="#{true}"/>
</bean>

2.SPEL可以通过ID引用其他Bean,属性,方法

<bean id="user" class="com.zbwang.demo.User">
    <property name="content1" value="#{saxophone}"/>
    <property name="content2" value="#{saxophone.content}"/>
    <property name="content3" value="#{contentGenerator.getContent()}"/>
    <!-- 可能引入NullPointerException -->
    <property name="content3" value="#{contentGenerator.getContent().toUpperCase()}"/>
    <!-- 使用?.确保左侧为空时将不再尝试调用toUpperCase方法 -->
    <property name="content3" value="#{contentGenerator.getContent()?.toUpperCase()}"/>
</bean>

3.在SPEL中,使用T()运算符会调用类作用域的方法和常量。

<bean id="user" class="com.zbwang.demo.User">
    <property name="content1" value="#{T(java.lang.Math).PI}"/>
    <property name="content2" value="#{T(java.lang.Math).random()}"/>
    
    <property name="content3" value="#{counter.total + 24}"/>
    <property name="equal1" value="#{counter.total == 80}"/>
    <property name="equal2" value="#{counter.total eq 80}"/>
    <property name="largeCircle" value="#{shape.kind == 'circle' and shape.perimeter gt 100 }"></property>
    <property name="isOutOfTime" value="#{ not product.available}"/>
    
    <property name="song" value="#{kenney.song != null?kenney.song:'Juliet'}"/>
    <property name="song" value="#{kenney.song != null?:'Juliet'}"/>
    
    <property name="email" value="#{user.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}"
    
</bean>

<util:list>元素是由Spring的util命名空间所定义的,创建了一个java.util.List类型的Bean.

<util:properties>加载了一个属性文件

<util:list id="cities">.......此处省略</util:list>    
<bean id="user" class="com.zbwang.demo.User">
    <!-- 获取list集合元素 -->
    <property name="chosenCity" value="#{cities[2]}"/>
    <property name="chosenCity" value="#{cities[T(java.lang.Math).random()*cities.size()]}"/>
    <!-- 获取Map元素 -->
    <property name="chosenCity" value="#{cities['Beijing']}"/>
</bean>

<util:properties id="settings" location="classpath:settings.properties"/>
<bean id="user" class="com.zbwang.demo.User">
  <property name="accessToken" value="#{settings['accessToken']}"/>
</bean>

4.SystemEnvironment包含了电脑所有的环境变量;SystemProperties包含了java启动所设置的所有属性(通常称为-D参数)

<bean id="user" class="com.zbwang.demo.User">
    <property name="javaHome" value="#{SystemEnvironment['JAVA_HOME']}"/>
    <property name="applicationHome" value="#{Systemproperties['application.home']}"/>
</bean>

5.Spring除了.?[]还提供了两种查询运算符.^[]和.$[],从集合中查出第一个和最后一个匹配项。

<bean id="user" class="com.zbwang.demo.User">
    <property name="aBigCity" value="#{cities.?[population gt 10000]}"/>
    <property name="aBigCity" value="#{cities.^[population gt 10000]}"/>
    <property name="aBigCity" value="#{cities.$[population gt 10000]}"/>
</bean>

6.集合投影是从集合的每个成员中选择特定的属性放入到一个新集合中。SPEL投影运算符.![]

<bean id="user" class="com.zbwang.demo.User">
    <property name="cityNames" value="#{cities.![name]}"/>
    <property name="aBigCity" value="#{cities.![name+' , '+state]}"/>
    <property name="aBigCity" value="#{cities.?[population gt 10000].![name]}"/>
</bean>

 

Spring Bean自动装配

<!-- 非首选Bean -->
<bean id="song" class="com.zbwang.Song" primary="false"/>
<!-- 自动装配时排除某些Bean -->
<bean id="song" class="com.zbwang.Song" autowire-candidate="false"/>
<!-- 构造器注入 -->
<bean id="song" class="com.zbwang.Song" autowire="constructor"/>

<bean id="song" class="com.zbwang.Song" autowire="autodetect"/>

默认情况下,default-autowire属性被设置为none

<beans ......
    default-autowire="byType">
</beans>
<bean id="user" class="com.zbwang.demo.User" autowire="byName">
    <property name="song"><null/></property>
</bean>

注意:不能混用constructor自动装配以及<constructor-arg>

 

可以使用Spring的context命名空间配置中的<context:annotation-config>元素,开启注解装配

<?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-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"
  >

<context:annotation-config/>
</beans>

@Autowired不仅可以标注setter方法,也可以标注自动装配Bean引用的任意方法。

当使用构造器装配时,只有一个构造函数可以将@Autowired的required属性设为true;当使用@Autowired标注多个构造器时,Spring会选择入参最多的那个构造器。

 

@Autowired(required=false)
private Instrument instrument;
    
@Autowired
@Qualifier("guitar")
private Instrument instrument;

 

使用@Autowired的类引入了对Spring的特定依赖,即使这个依赖只是一个注解。

JCP(Java Community Process)最近发不了Java依赖注入规范,JCP将其称为JSR-330,更通用的叫法是at inject;spring 3 开始兼容JSR-330。

 

Spring 3.0引入了@Value,一个新的装配注解

@Value("FloorFiller")
private String song;

@Value("#{systemProperties.myfavoriteSong}")
private String song;

<context:component-scan />除了完成<context:annotation-config/>的工作,还允许Spring自动检测定义Bean。

它会自动扫描指定的包以及其所有子包——构造性型注解所标注的类,自动注册为SpringBean的类。

构造型注解标注的类,Bean ID默认为无限定类名。也可以显示命名,例如@Component("eddie")

<context:component-scan base-package="com.zbwang.springidol">
  <!--注册Instrument的所有实现类-->
    <context:include-filter type="assignable" expression="com.zbwang.springidol.Instrument"/>
    <context:exclude-filter type="annotation" expression="com.zbwang.springidol.SkipIt"/>
</context:component-scan>
意思为除了使用SkipIt注解的类以外,其他所有派生于Instrument的类都需要注册为Spring的Bean. 

 使用Spring基于java的配置 @Configuration @Bean

posted @ 2015-03-15 23:29  nozbwang  阅读(289)  评论(0编辑  收藏  举报