Spring学习笔记—Spring之旅 . -----装配Bean

来源:互联网 发布:淘宝原单是真的吗 编辑:程序博客网 时间:2024/05/01 20:28

                         spring学习笔记—Spring之旅

1.Spring简介

    Spring是一个开源框架,最早由Rod Johnson创建,并在《Expert One-on-One:J2EE Design and Development》这本著作中进行了介绍。Spring是为了解决企业级应用开发的复杂性而创建的,使用Spring可以让简单的JavaBean实现之前只有EJB才能完成的事情。但Spring不仅仅局限于服务器开发,任何Java应用都能在简单性、可测试性和松耦合等方面从Spring中获益。

 1.1 简化Java开发

    Spring通过激发POJO的潜能、依赖注入降低耦合、基于切面进行声明式编程和使用模板消除样板式代码等方式简化Java开发。
    依赖注入让相互协作的软件组件保持松散耦合,而AOP编程允许你把遍布应用各处的功能分离出来形成可重用的组件。
[html] view plain copy
 print?
  1. <bean id="fileUploadServiceAop" class="com.ouc.mkhl.supplier.security.util.FileUploadServiceAop"></bean>  
  2.     <aop:config>  
  3.         <aop:pointcut id="fileUploadAudit" expression="execution(* com.ouc..service.impl.FileUploadServiceImpl.*(..))"/>    
  4.         <aop:aspect ref="fileUploadServiceAop" order="5">  
  5.             <aop:before pointcut-ref="fileUploadAudit" method="beforeExecute"/>  
  6.             <aop:after pointcut-ref="fileUploadAudit" method="afterExecute" />  
  7.         </aop:aspect>         
  8.     </aop:config>  
   这里使用Spring的AOP配置的命名空间把fileUploadServiceAop Bean声明为一个切面。首先,必须把fileUploadServiceAop声明为一个Bean,然后在<aop:aspect>元素中引用该Bean。为了进一步定义切面,必须使用<aop:before>来声明在* com.ouc..service.impl.FileUploadServiceImpl.*(..)方法执行前调用fileUploadServiceAop的beforeExecute()方法,这种方式被为前置通知。同时还必须使用<aop:after>声明在* com.ouc..service.impl.FileUploadServiceImpl.*(..)方法执行后调用afterExecute()方法,这种方式被称为后置通知。

 1.2 容纳你的Bean

   1.Spring两种不同的容器实现:Bean工厂应用上下文
   Bean工厂(bean factories,由org.springframework.beans.factory.BeanFactory接口定义)是最简单的容器,提供基本的DI支持。
   应用上下文(application由org.springframework.context.ApplicationContext接口定义)基于BeanFactory之上构建,并提供面向应用的服务,例如从属性文件解析文本信息的能力,以及发布应用事件给感兴趣的事件监听者的能力。
  Spring自带了几种类型的应用上下文。以下列出常用的三种:
  ● ClassPathXmlApplicationContext——从类路径下的XML配置文件中加载上下文定义,把应用上下文定义文件当作类资源。
  ● FileSystemXmlApplicationContext——读取文件系统下的XML配置文件并在加载上下文定义。
  ● XmlWebApplicationContext——读取Web应用下的XML配置文件并装载上下文定义。
  例:如下代码展示了如何加载一个FileSystemXmlApplicationContext:
[html] view plain copy
 print?
  1. ApplicationContext context = new FileSystemXmlApplicationContext("D:/test.xml");  
  类似地,也可以使用ClassPathXmlApplicationContext从应用的类路径下加载应用上下文:
[html] view plain copy
 print?
  1. ApplicationContext context = new ClassPathXmlApplicationContext("test.xml");  
  使用FileSystemXmlApplicationContext和使用ClassPathXmlApplicationContext的区别在于:FileSystemXmlApplicationContext在指定的文件系统下查找test.xml文件;而ClassPathXmlApplicationContext是在所有的类路径(包含JAR文件)下查找test.xml文件。
  通过现有的应用上下文引用,你可以调用应用上下文的getBean()方法从Spring容器中获取Bean。
  
  2.Bean的生命周期:
    1)Spring对Bean进行实例化。
    2)Spring将值和Bean的引用注入进Bean对应的属性中。
    3)如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()接口方法。
    4)如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()接口方法,将BeanFactory容器实例传入。
    5)如果Bean实现ApplicationContextAware接口,Spring将调用setApplicationContext()接口方法,将应用上下文的引用传入。
    6)如果Bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitializing()接口方法。
    7)如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()接口方法。类似地,如果Bean使用init-method声明了初始化方法,该方法也会被调用。
    8)如果Bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitializing()接口方法。
    9)此刻,Bean已经准备就绪,可以被应用程序使用了,它们将一直驻留在应用上下文中,直到该应用上下文被销毁。
   10)如果Bean实现了DisposableBean接口,Spring将调用它的destroy()接口方法。同样,如果Bean使用destroy-method声明了销毁方法,该方法也会被调用。

 1.3 Spring框架的组成

  1.Spring框架6个不同的功能模块组成:
   核心Spring容器、Spring的AOP模块、数据访问与集成、Web和远程调用、Instrumentation设备支持和测试。

   2.Spring Portfolio框架和类库
    1)Spring Web Flow建立于Spring MVC框架之上并为基于流程的会话式Web应用(例:购物车、向导)提供支持。
    2)Spring Web Service提供了契约优先的Web Service模型,服务的实现都是为了满足服务的契约而编写的。
    3)Spring Security和Spring AOP为Spring应用提供了声明式安全机制。
    4)Spring Integration提供了几种通用的应用集成模式的Spring声明式风格的实现。
    5)Spring Batch用于辅助批处理程序的开发。
    6)Spring Social是Spring的一个社交网络扩展模块。
    7)Spring Mobile是Spring新的扩展模块用于支持移动Web应用开发。
    8)Spring Dynamic Modules整合了Spring的声明式依赖注入和OSGi的动态组件模型。
    9)Spring LDAP是基于Spring风格的基于模板的LDAP访问,消除了因使用LDAP而产生的样板式代码。
    10)Spring Rich Client是一个富应用工具箱,为Swing赋予了Spring的魔力。
    11)Spring .NET提供了相同的松耦合和面向切面的Spring特性,自带了简化.NET开发的ADO.NET、NHibernate、ASP.NET和MSMQ等多个模块。
    12)Spring-Flex集成包使得Flex和AIR应用可以使用BlazeDS与服务端的Spring Bean进行通信,还包含Spring Roo的扩展,可用于快速开发Flex应用。
    13)Spring Roo提供了一个可以快速开发Spring应用的交互工具环境,融入了最近几年形成的最佳实践。
    14)Spring Extensions:
     ①Python语言的Spring实现;
     ②Blob Storage;
     ③db4o和CouchDB的持久化框架;
     ④基于Spring的工作流管理类库;
     ⑤Spring Security的Kerberos和SAML的扩展。

 1.4 Spring新功能

   1.Spring2.5新特性:
    Spring2.5之前的版本都是采用基于XML的配置,Spring2.5重大意义在于拥抱注解驱动开发。
    ● 使用@Autowired实现基于注解驱动的依赖注入和使用@Qualifier实现细粒度的自动装配(auto-wiring)控制。
    ● 支持JSR-250注解,包括支持命名资源依赖注入的@Resource,以及对生命周期方法支持的@PostConstruct和@PreDestroy。
    ● 自动扫描使用@Component注解(或其他构造型注解)所标注的Spring组件。
    ● 一个全新的基于注解驱动的Spring MVC编程模型,极大简化了Spring Web开发。
    ● 基于JUnit4和注解的一个新的集成测试框架。
    ● 完全支持Java 6和Java EE 5,涵盖JDBC4.0、JTA 1.1、JavaMail 1.4和JAX-WS 2.0。
    ● 通过Bean的名字来编织切面的新的Bean命名切入点表达式。
    ● 内嵌支持AspectJ的类加载器织入。
    ● 新的XML命名空间,包括配置应用上下文细节的context命名空间和配置消息驱动Bean的jms命名空间。
    ● 支持在SqlJdbcTemplate中使用命名参数。

   2.Spring3.0新特性:
    ● Spring MVC全面支持Rest,Spring MVC控制器响应响应REST风格的URL并返回XML、JSON、RSS或者其他适宜的响应。
    ● 新的表达式语言把Spring的依赖注入带到了一个新的高度,允许注入各种来源,包含其他Bean和系统属性。
    ● Spring MVC新的注解,包含@CookieValue和@RequestHeader,分别从Cookie和请求头中获取值。
    ● 一个新的XML命名空间,用来减少Spring MVC配置。
    ● 支持基于JSR-302注解的声明式校验。
    ● 支持新的JSR-330依赖注入规范。
    ● 通过注解驱动声明异步和调度方法。
    ● 一个新的注解驱动的配置模型,几乎可以避免使用XML进行Spring配置。

    ● Spring Web Service项目的OXM功能已被迁移到Spring框架核心。



                                              spring学习笔记—装配Bean

   在Spring中,对象无需自己负责查找或创建与其关联的其他对象。相反,容器负责把需要相互协作的对象引用赋予各个对象。创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入的本质。

   1.声明Bean

     1.1 创建Spring配置

      在XML文件中声明Bean时,Spring配置文件的根元素是来源于Spring beans命名空间所定义的<beans>元素。以下是一个典型的Spring XML配置文件:

[html] view plain copy
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <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"  
  3.     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"  
  4.     xmlns:lang="http://www.springframework.org/schema/lang" xmlns:util="http://www.springframework.org/schema/util"  
  5.     xsi:schemaLocation="  
  6.      http://www.springframework.org/schema/beans   
  7.      http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  8.      http://www.springframework.org/schema/tx  
  9.      http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
  10.      http://www.springframework.org/schema/aop   
  11.      http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
  12.      http://www.springframework.org/schema/jee   
  13.      http://www.springframework.org/schema/jee/spring-jee-3.1.xsd  
  14.      http://www.springframework.org/schema/context  
  15.      http://www.springframework.org/schema/context/spring-context-3.1.xsd  
  16.      http://www.springframework.org/schema/lang  
  17.      http://www.springframework.org/schema/lang/spring-lang-3.1.xsd  
  18.      http://www.springframework.org/schema/util  
  19.      http://www.springframework.org/schema/util/spring-util-3.1.xsd">  
  20.   
  21.  <!-- Bean declaration go here -->  
  22.   
  23. </beans></span>  
     在<beans>元素内,可以放置所有的Spring配置信息,包括<bean>元素的声明。

     Spring核心框架自带的10个命名空间配置如下:

   

    1.2 声明一个简单的Bean

    <bean>元素是Spring中最基本的配置单元,通过该元素Spring将创建一个对象。Spring使用反射来创建Bean。

    1.3 通过构造器注入

     1) 通过构造器注入对象引用
[html] view plain copy
 print?
  1. <bean id="zookeeperSources" class="com.dangdang.config.service.easyzk.support.spring.ZookeeperSourceFactoryProxy" >  
  2.     <constructor-arg name="appName" value="${server.name}" />  
  3.     <constructor-arg name="configFactory" ref="configFactory" />  
  4.     <constructor-arg name="nodes" value=""/>  
  5. </bean></span>  
     2) 通过工厂化方法创建Bean
[html] view plain copy
 print?
  1. <bean id="zookeeperSources" class="com.dangdang.config.service.ZookeeperSource" factory-method="create"/>  

    1.4 Bean的作用域

    所有的Spring Bean默认都是单例。当容器分配一个Bean时,它总返回Bean的同一个实例。为了让Spring在每次请求时都为Bean产生一个新的实例,我们只需配置Bean的scope属性为prototype。
[html] view plain copy
 print?
  1. <bean id="zookeeperSources" class="com.dangdang.config.service.ZookeeperSource" scope="prototype"/></span>  
      Spring的作用域选项:
   

    1.5 初始化和销毁Bean

    为Bean定义初始化和销毁操作,只需使用init-method和destroy-method参数来配置<bean>元素。init-method属性指定了在初始化Bean时要调用的方法,destroy-method属性指定了Bean从容器移除前要调用的方法。
[html] view plain copy
 print?
  1. <bean id="auditor" class="com.springinaction.springidol.Auditor" init-method="turnOnLights" destroy-method="turnOffLights" /></span>  
       可以使用<beans>元素的default-init-method和default-destroy-method为应用上下文中所有的Bean设置共同的初始化和销毁方法。
[html] view plain copy
 print?
  1. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  2.      xsi:schemaLocation="  
  3.      http://www.springframework.org/schema/beans/spring-beans-3.1.xsd" default-init-method="  
  4. turnOnLights" default-destroy-method="turnOffLights">  
  5. </beans></span>  

2.注入Bean属性

   2.1注入简单值

[html] view plain copy
 print?
  1. <bean id =“kenny" class="com.ouc.springinaction.test">  
  2.      <property name ="song" value="Bells" />  
  3. </bean>  
  一旦test被实例化,Spring就会调用<property>元素所指定属性的setter方法为该属性注入值。

  2.2 引用其他Bean

[html] view plain copy
 print?
  1. <bean id =“saxon" class="com.ouc.springinaction.saxontest"></bean>  
  2. <bean id =“kenny" class="com.ouc.springinaction.test2">  
  3.      <property name ="song" value="Bells" />  
  4.      <property name ="saxonIns" ref="saxon" />  
  5. </bean>  
  Spring提倡面向接口编程,面向接口编程与依赖注入协作实现了松散耦合。

 2.3 注入内部Bean

[html] view plain copy
 print?
  1. <bean id =“saxon" class="com.ouc.springinaction.saxontest"></bean>  
  2. <bean id =“kenny" class="com.ouc.springinaction.test2">  
  3.      <property name ="song" value="Bells" />  
  4.      <property name ="saxonIns">         
  5.         <bean class="com.ouc.springinaction.saxontest">  
  6.      /property>  
  7. </bean>  
    内部Bean是通过直接声明一个<bean>元素作为<property>元素的子节点而定义的。
    内部Bean没有ID属性,使用内部Bean的最大缺点:不能被复用,内部Bean仅适用于一次注入,而且不能被其他Bean所引用。

  2.4 使用Spring的命名空间p装配属性

  命名空间p的schema URI为http://www.springframework.org/schema/p.
[html] view plain copy
 print?
  1. <bean id =“kenny" class="com.ouc.springinaction.test3">  
  2.      p:song = "Bells"  
  3.      p:saxonIns-ref = "saxon" />  
  4. </bean>  
   使用p:作为<bean>元素所有属性的前缀来装配Bean的属性。-ref后缀作为一个标识来告知Spring应该装配一个引用。

 2.5 装配集合

 Spring提供了4种类型的集合配置元素。

   <props>要求键和值都必须为String类型,而<map>允许键和值可以是任意类型
[html] view plain copy
 print?
  1. <bean id =“hank" class="com.ouc.springinaction.test4">  
  2.      <property name ="ins">  
  3.        <set>  
  4.          <ref bean = "guitar" />      
  5.          <ref bean = "cymbal" />  
  6.          <ref bean = "harmonica" />  
  7.          <ref bean = "harmonica" />  
  8.        </set>  
  9.      </property>  
  10. </bean>  
[html] view plain copy
 print?
  1. <bean id =“hank" class="com.ouc.springinaction.test4">  
  2.      <property name ="ins">  
  3.        <list>  
  4.          <ref bean = "guitar" />      
  5.          <ref bean = "cymbal" />  
  6.          <ref bean = "harmonica" />  
  7.        </list>  
  8.      </property>  
  9. </bean>  
    装配Map集合
[html] view plain copy
 print?
  1. <bean id =“hank" class="com.ouc.springinaction.test4">  
  2.      <property name ="ins">  
  3.        <map>  
  4.          <entry key="GUITAR" value-ref = "guitar" />      
  5.          <entry key="GUITAR1" value-ref = "guitar1" />    
  6.          <entry key="GUITAR2" value-ref = "guitar2" />        
  7.        </map>  
  8.      </property>  
  9. </bean>  
 
    装配Properties集合
[html] view plain copy
 print?
  1. <bean id =“hank" class="com.ouc.springinaction.test4">  
  2.      <property name ="ins">  
  3.        <props>  
  4.          <prop key="GUITAR"> STRUM </prop>    
  5.          <prop key="CYMBAL"> CRASH </prop>    
  6.        </props>  
  7.      </property>  
  8. </bean>  
   ● <property> 元素用于把值或Bean引用注入到Bean的属性中。
   ● <props> 元素用于定义一个java.util.Properties类型的集合值。
   ● <prop> 元素用于定义<props>集合的一个成员。
   装配空值
   为了覆盖自动装配的值或不能完全确定属性的值是否为null,此时,必须显示地为该属性装配一个null值。
[html] view plain copy
 print?
  1. <property name ="nullIns"><null/></property>  

  2.6 使用表达式装配

  Spring表达式语言(SpEL)拥有许多特性,包括:
  ● 使用Bean的ID来引用Bean;
  ● 调用方法和访问对象的属性;
  ● 对值进行算术、关系和逻辑运算;
  ● 正则表达式匹配;
  ● 集合操作。
 字面值
[html] view plain copy
 print?
  1. <property name="cappacity" value="#{1e4}" />  
 引用Bean、Properties和方
[html] view plain copy
 print?
  1. <property name="ins" value="#{saxno.song}" />  
  2. <property name="ins" value="#{saxno.song()?.toUpperCase()}" />  
  使用?.运算符代替点(.)来访问toUpperCase()方法。
  操作类
  使用T()运算符会调用类作用域的方法和常量,通过该运算符可以访问指定类的静态方法和常量。
[html] view plain copy
 print?
  1. <property name="mathplier" value="#{T(java.lang.Math).PI}" />  
  2. <property name="randomNum" value="#{T(java.lang.Math).random()}" />  
 使用SpEL进行数值运算
[html] view plain copy
 print?
  1. <property name="area" value="#{T(java.lang.Math).PI * circle.radius ^ 2}" />  
 比较值
[html] view plain copy
 print?
  1. <property name="hasCap" value="#{count.total le 10000}" />  
  逻辑表达式
[html] view plain copy
 print?
  1. <property name="outStock" value="#{!pro.available}" />  
  2. <property name="outStock" value="#{not pro.available}" />  
  条件表达式
[html] view plain copy
 print?
  1. <property name="song" value="#{keny.song != null ? keny.song : 'Green'}" />  
  2. <property name="song" value="#{keny.song ?: 'Green'}" />  
  SpEL正则表达式
[html] view plain copy
 print?
  1. <property name="validEmail" value="#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}" />  
  使用<util:list>元素在Spring里配置一个包含City对象的List集合。
[html] view plain copy
 print?
  1. <util:list id ="cities">  
  2.   <bean class="com.habuma.spel.city"  
  3.      p:name="Chicago" p:state="IL" p:population="2556321" />  
  4.      p:name="Chicago1" p:state="IL1" p:population="2556312" />  
  5.      p:name="Chicago2" p:state="IL2" p:population="2556311" />  
  6. </util:list>  
    访问集合成员
[html] view plain copy
 print?
  1. <property name="choseCity" value="#{cities[2]}" />  
  2. <property name="choseCity" value="#{cities['Chicago']}" />  
   两种特殊的选择属性的方式:systemEnvironment和systemProperties。
   systemEnvironment包含了应用程序所在机器上的所有环境变量。
[html] view plain copy
 print?
  1. <property name="homePath" value="#{systemEnvironment['HOME']}" />  
   systemProperties包含了Java应用程序启动时所设置的所有属性。
[html] view plain copy
 print?
  1. <property name="homePath" value="#{systemProperties['app.home']}" />  
  查询集合成员
  从城市集合中查询人口多于10000的城市。
  使用查询运算符(.?[])
[html] view plain copy
 print?
  1. <property name="bigCities" value="#{cities.?[population gt 10000]}" />  
  使用".^[]"和".$[]",从集合中查询第一匹配项和最后一个匹配项。
 投影集合
 集合投影是从集合的每一个成员中选择特定的属性放入一个新的集合中。
 用(.![])投影运算符投影集合。
[html] view plain copy
 print?
  1. <property name="cityNames" value="#{cities.![name]}" />  

0 0
原创粉丝点击