`

spring知识总结

阅读更多

bean属性及构造器参数:直接量(基本类型、Strings类型等。)
<value/>元素通过字符串来指定属性或构造器参数的值。正如前面所提到的,JavaBean PropertyEditor将用于把字符串从java.lang.String类型转化为实际的属性或参数类型。
Xml代码

<bean id="myDataSource" destroy-method="close" 
  class="org.apache.commons.dbcp.BasicDataSource"> 
  <!-- results in a setDriverClassName(String) call --> 
     <property name="driverClassName"> 
       <value>com.mysql.jdbc.Driver</value> 
      </property> 
      <property name="url"> 
        <value>jdbc:mysql://localhost:3306/mydb</value> 
     </property> 
     <property name="username"> 
      <value>root</value> 
    </property> 
  </bean> 

<bean id="myDataSource" destroy-method="close"
    class="org.apache.commons.dbcp.BasicDataSource">
  <!-- results in a setDriverClassName(String) call -->
  <property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
    <value>jdbc:mysql://localhost:3306/mydb</value>
  </property>
  <property name="username">
    <value>root</value>
  </property>
</bean>



idref元素用来将容器内其它bean的id传给<constructor-arg/> 或 <property/>元素,同时提供错误验证功能。
Xml代码

   <bean id="theTargetBean" class="..."/> 
    <bean id="theClientBean" class="..."> 
       <property name="targetName"> 
           <idref bean="theTargetBean" /> 
       </property> 
    </bean> 

<bean id="theTargetBean" class="..."/>
 <bean id="theClientBean" class="...">
    <property name="targetName">
        <idref bean="theTargetBean" />
    </property>
</bean>


上述bean定义片段完全地等同于(在运行时)以下的片段:
Xml代码

   <bean id="theTargetBean" class="..."/> 
    <bean id="client" class="..."> 
        <property name="targetName"> 
          <value>theTargetBean</value> 
       </property> 
    </bean> 

<bean id="theTargetBean" class="..."/>
<bean id="client" class="...">
    <property name="targetName">
        <value>theTargetBean</value>
    </property>
</bean>


第一种形式比第二种更可取的主要原因是,使用idref标记允许容器在部署时 验证所被引用的bean是否存在。而第二种方式中,传给client bean的targetName属性值并没有被验证。

如果被引用的bean在同一XML文件内,且bean名字就是bean id,那么可以使用local属性,此属性允许XML解析器在解析XML文件时来对引用的bean进行验证。
如:
Xml代码

   1. <idref local="theTargetBean"/> 

<idref local="theTargetBean"/>



depends-on属性可以用于当前bean初始化之前显式地强制一个或多个bean被初始化。例如,当类中的静态块的初始化被时,如数据库驱动的注册. 若需要表达对多个bean的依赖,可以在'depends-on'中将指定的多个bean名字用分隔符进行分隔,分隔符可以是逗号、空格及分号等。
Xml代码

   1. <bean id="beanOne" class="ExampleBean" depends-on="manager"/> 
   2. <bean id="manager" class="ManagerBean" /> 

<bean id="beanOne" class="ExampleBean" depends-on="manager"/>
<bean id="manager" class="ManagerBean" />



ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化。如果你不想让一个singleton bean在ApplicationContext实现在初始化时被提前实例化,那么可以将bean设置为延迟实例化。一个延迟初始化bean将告诉IoC 容器是在启动时还是在第一次被用到时实例化。在XML配置文件中,延迟初始化将通过<bean/>元素中的lazy-init属性来进行控制。

当采用XML格式配置bean时,<bean/>元素的 autowire-candidate属性可被设为false,这样容器在查找自动装配对象时将不考虑该bean。

根据经验,对所有有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。

实现了Spring的InitializingBean和DisposableBean这两个标志接口的bean在初始化和析构时容器会调用前者的afterPropertiesSet()方法,以及后者的destroy()方法。

要避免使用InitializingBean接口(而且不鼓励使用该接口,因为这样会将代码和Spring耦合起来)可以在Bean定义中指定一个普通的初始化方法,即在XML配置文件中通过指定init-method属性来完成。同样要避免使用DisposableBean标志接口(而且不鼓励使用该接口,因为这样会将代码与Spring耦合在一起)可以在bean定义中指定一个普通的析构方法,即在XML配置文件中通过指定destroy- method属性来完成。

顶层<beans/>元素'default-init-method'属性的出现意味着Spring IoC容器会把bean上名为'init'的方法识别为初始化方法回调,并且当bean被创建和装配的时候,如果bean类具有这样的方法,它将会在适当的时候被调用。 类似的,配置析构方法回调是在顶层<beans/>元素上使用'default-destroy-method'属性。

对于实现了org.springframework.beans.factory.BeanFactoryAware接口的类,当它被 BeanFactory创建后,它会拥有一个指向创建它的BeanFactory的引用。也就是让bean能持有一个指向BeanFactory的引用. 但是一般来说应该尽量避免使用,因为这样将使代码与Spring耦合在一起,而且也有违反转控制的原则(协作者应该作为属性提供给bean)。

ObjectFactoryCreatingFactoryBean 与BeanFactoryAware的区别在于它没有违反控制反转这一原则, 因为某个bean在注入了该FactoryBean之后, 所依赖的bean将由该ObjectFactory来提供, 这样可以对依赖bean做更多的工作.

假如bean实现了org.springframework.beans.factory.BeanNameAware接口并被部署在一个 BeanFactory中,BeanFactory会通过该接口的setBeanName()方法以告知其被部署时的bean id。在bean属性被设置完成之后,在像InitializingBean的afterPropertiesSet或是自定义init-method这样的初始化回调执行之前,该接口的回调方法会被调用。

org.springframework.beans.factory.config.BeanPostProcessor接口有两个回调方法可供使用。当一个该接口的实现类被注册(如何使这个注册生效请见下文)为容器的后置处理器(post-processor)后,对于由此容器所创建的每个 bean实例在初始化方法(如afterPropertiesSet和任意已声明的init方法)调用前,后置处理器都会从容器中分别获取一个回调。后置处理器可以随意对这个bean实例执行它所期望的动作,包括完全忽略此回调。一个bean后置处理器通常用来检查标志接口,或者做一些诸如将一个bean 包装成一个proxy的事情;一些Spring AOP的底层处理也是通过实现bean后置处理器来执行代理包装逻辑。
请不要将BeanPostProcessor标记为延迟初始化。如果你这样做,Spring容器将不会注册它们,自定义逻辑无法得到应用。假如你在<beans/>元素的定义中使用了'default-lazy-init'属性,请确信你的各个BeanPostProcessor标记为'lazy-init="false"'
在Spring的BeanPostProcessor实现中调用标志接口或使用注解是扩展Spring IoC容器的常用方法。

BeanFactoryPostProcessor可以对bean的定义(配置元数据)进行处理。也就是说,Spring IoC容器允许BeanFactoryPostProcessor在容器实际实例化任何其它的bean之前读取配置元数据,并有可能修改它。配置多个 BeanFactoryPostProcessor。你还能通过设置'order'属性来控制BeanFactoryPostProcessor的执行次序(仅当BeanFactoryPostProcessor实现了Ordered接口时你才可以设置此属性,因此在实现 BeanFactoryPostProcessor时,就应当考虑实现Ordered接口)
PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,可以将BeanFactory定义中的一些属性值放到另一个单独的标准Java Properties文件中。
PropertyOverrideConfigurer是另外一个bean factory processor, 他的作用是可以使用properties文件中的值覆盖已有的值

一个processor是改变实例, 一个是改变定义

FactoryBean接口是插入到Spring IoC容器用来定制实例化逻辑的一个接口点。如果你有一些复杂的初始化代码用Java可以更好来表示,而不是用(可能)冗长的XML,那么你就可以创建你自己的FactoryBean,并在那个类中写入复杂的初始化动作,然后把你定制的FactoryBean插入容器中。

-----spring bean id name
id属性命名必须满足XML的命名规范,因为id其实是XML中就做了限定的。总结起来就相当于一个Java变量的命名:不能以数字,符号打头,不能有空格,如123,?ad,"ab "等都是不规范的,Spring在初始化时就会报错

name属性则没有这些限定,你可以使用几乎任何的名称,如?ab,123等,但不能带空格,如"a b"," abc",,这时,虽然初始化时不会报错,但在getBean()则会报错

但配置文件中允许出现两个name相同的<bean>,在用getBean()返回实例时,后面一个Bean被返回,应该是前面那个<bean>被后面同名的   <bean>覆盖了。有鉴于此,为了避免不经意的同名覆盖的现象,尽量用id属性而不要用name属性。

name属性可以用,隔开指定多个名字,如<bean name="b1,b2,b3">,相当于多个别名,这时通过getBean("a1") getBean("a2") getBean("a3")返回的都是同一个实例(假设是singleton的情况)

如果id和name都没有指定,则用类全名作为name,如<bean class="com.stamen.BeanLifeCycleImpl">,则你可以通过
   getBean("com.stamen.BeanLifeCycleImpl")返回该实例。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics