Springframework.beans

来源:互联网 发布:火星知乎 编辑:程序博客网 时间:2024/06/06 20:05

Springframework 一 beans

这里写图片描述


beans

在Spring技术中是基于组件的
最基本了是最常用的单元
其实实例保存在Spring的容器当中

Bean通常被定义在配置文件当中,Bean实例化由Spring的Ioc容器进行管理,Bean的实例可以通过Beanfactory进行访问,实际上大部分J2EE应用,Bean是通过ApplicationContext来访问的,ApplicationContext是BeanFactory的子接口,功能要比BeanFactory强大许多

对于我们而言,我们使用Spring框架所做的就是两件事:开发Bean、配置Bean。对于Spring矿建来说,它要做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法完成“依赖注入”。


<beans…/>元素是Spring配置文件的根元素,<bean…/>元素师<beans../>元素的子元素,<beans…/>元素可以包含多个<bean…/>子元素,每个<bean…/>元素可以定义一个Bean实例,每一个Bean对应Spring容器里的一个Java实例定义Bean时通常需要指定两个属性。

Id:确定该Bean的唯一标识符,容器对Bean管理、访问、以及该Bean的依赖关系,都通过该属性完成。Bean的id属性在Spring容器中是唯一的。

Class:指定该Bean的具体实现类。注意这里不能使接口。通常情况下,Spring会直接使用new关键字创建该Bean的实例,因此,这里必须提供Bean实现类的类名。

定义一个Bean的简单配置

/** * @create 2017-05-19 13:10 **/public class Bean {    private String name;    private int age;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}
<?xml version="1.0" encoding="UTF-8"?>  <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xmlns="http://www.springframework.org/schema/beans"      xsi:schemaLocation="http://www.springframework.org/schema/beans      http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">      <!-- 定义第一个Bean实例:bean1 -->      <bean id="bean" class="com.yang.Bean" />        </bean> 

Spring容器集中管理Bean的实例化,Bean实例可以通过BeanFactory的getBean(Stringbeanid)方法得到。BeanFactory是一个工厂,程序只需要获取BeanFactory引用,即可获得Spring容器管理全部实例的引用。程序不需要与具体实例的实现过程耦合。大部分Java EE应用里,应用在启动时,会自动创建Spring容器,组件之间直接以依赖注入的方式耦合,甚至无须主动访问Spring容器本身。

当我们在配置文件中通过< <bean id="bean" class="com.yang.Bean"/>方法配置一个Bean时,这样就需要该Bean实现类中必须有一个无参构造器。故Spring底层相当于调用了如下代码: Bean bean= new Bean()

Bean的别名:
   通过alias属性指定:

<alias name=”bean” alias=”aliasBean”/>  

Bean注入

基本类型和String

用到Value元素XML解析器以String类型解析出数据

如果属性不是String类型,属性值会通过PropertyEditors转换为其他类型
注入Bean

-ref元素进行标识

Ref元素通常有两个属性:

bean:指定不在同一个XML文件中的bean的id

local:指定在同一个XML文件中的bean的id

<bean id="bean" class="com.yang.Bean"><property name="name"><ref bean="其他的bean的id"/></property></bean>

value和ref的区别:

使用ref元素,可以让Spring在部署时验证依赖的Bean是否真实存在

使用value元素,进行指定仅在创建Bean实例时做验证,会导致错误的延时出现,而且还会带来额外的类型转制开销

集合注入:

map

<bean id="bean" class="com.yang.Bean">        <property name="map">            <map>                <entry key="key1">                    <value>value1</value>                </entry>                <entry key="key2">                    <value>key2</value>                </entry>            </map>        </property>    </bean>

list:

<bean id="bean" class="com.yang.Bean">        <property name="lists">        <list>        <value>1</value>        <value>2</value>        <value>3</value>        </list>        </property>    </bean>

set

<bean id="bean" class="com.yang.Bean"> < property  name ="interest" >                 < set >                     < value > 唱歌 </ value >                     < value > 跳舞 </ value >                     < value > 书法 </ value >                 </ set >        </ property >  </bean>   

props:

<bean id="bean" class="com.yang.Bean"> <property name="props">  <props>    <prop key="key1">value1</prop>    <prop key="key2">value2</prop>  </props> </property></bean>

容器中Bean的作用域
当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。
Spring支持5种作用域:
   Singleton:单例模式。在整个SpringIoC容器中,使用singleton定义的Bean将只有一个实例。
   Prototype:原型模式。每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例。
   request:对于每次HTTP请求,使用request定义的Bean都将产生一个新的实例,即每次HTTP请求都会产生不同的Bean实例。当然只有在WEB应用中使用Spring时,该作用域才真正有效。
   session:对于每次HTTPSession,使用session定义的Bean都将产生一个新的实例时,即每次HTTP Session都将产生不同的Bean实例。同HTTP一样,只有在WEB应用才会有效。
   global session:每个全局的HTTPSession对应一个Bean实例。仅在portlet Context的时候才有效。

比较常用的singleton和prototype。如果一个Bean实例被设置为singleton,那么每次请求该Bean时都会获得相同的实例。容器负责跟踪Bean实例的状态,负责维护Bean实例的生命周期行为。如果一个Bean实例被设置为prototype,那么每次请求该di的Bean,Spring都会创建一个新的Bean实例返回给程序,在这种情况下,Spring容器仅仅使用new关键字创建Bean实例,一旦创建成功,容器将不会再跟踪实例,也不会维护Bean实例的状态。

如果我们不指定Bean的作用域,则Spring会默认使用singleton作用域。

Java在创建Java实例时,需要进行内存申请。销毁实例时,需要完成垃圾回收。这些工作都会导致系统开销的增加。因此,prototype作用域Bean的创建、销毁代价会比较大。而singleton作用域的Bean实例一旦创建成功,可以重复使用。因此,除非必要,否则尽量避免将Bean的作用域设置为prototype。

设置Bean的作用域是通过scope属性来指定。可以接受Singleton、prototype、request、session、global session 5个值。

    <?xml version="1.0" encoding="UTF-8"?>      <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xmlns="http://www.springframework.org/schema/beans"          xsi:schemaLocation="http://www.springframework.org/schema/beans          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">          <!-- 配置一个singleton Bean实例:默认 -->          <bean id="bean" class="com.yang.Bean" scope="singleton" />          <!-- 配置一个prototype Bean实例 -->          <bean id="bean2" class="com.yang.Bean2" scope="prototype"/>      </beans>  
    public class SpringBeanTest {          public static void main(String[] args) {              ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");              //判断两次请求singleton作用域的Bean实例是否相等              System.out.println(ctx.getBean("bean1")==ctx.getBean("bean1"));              //判断两次请求prototype作用域的Bean实例是否相等              System.out.println(ctx.getBean("bean2")==ctx.getBean("bean2"));          }      }  

程序运行结果如下

 true false

Bean管理生命周期

这里写图片描述

Spring可以管理实例化bean之间以及销毁之前的行为

注入依赖关系之后:

   使用init-method属性:通过指定init-method属性,确定某个方法应该在Bean依赖关系结束之后执行。这种方式无需要将代码与Spring的接口耦合在一起代码污染极小。通常在bean当中进行方法定义如init()方法,然后在配置文件Bean元素中加入init-method属性来实现这个过程。
  实现InnitializingBean接口:这种方式无须指明init-method属性,当窗口依赖注入以后,会自动调用afterPropertiesSet方法,它和init-method执行效果一样,但这种方式属于侵入性的代码设计不推荐使用

销毁Bean之前:

  destroy-method:用于在执行Bean销毁之前所执行的方法,这种方式和init-method一样无压需要代码与Spring的接口耦合在一起代码污染极小。在bean中加入destory-method属性和实现这个过程
实现DisposeableBean接口:无需要指明destory-method属性,当容器依赖注入以后,会自动调用destroty方法,属于侵入性代码设计不推荐使用

Bean的继承

  什么是Bean继承呢?继承是指子bean可以从父bean继承配置信息,也可以覆盖特定的配置信息,或者在父bean的基础之上加入新的配置信息,其实质类似于java中的子类与父类的继承关系,利用继承可以节省很多配置工作,在实际的项目应用中,共有的配置会配置成模板,供子bean继承,如果2个bean之间配置信息大致相同,可以采用bean的继承来减少配置工作。

Bean的模板:

  在Spring中既然要将公用的配置,配置称模板,这个模板不需要被实例化,而仅仅作为子bean的模板来使用,但在ApplicationContext或者BeanFactory默认会初始化所有的bean.

使用abstract属性,该属性可以阻止模板被实例化

abstract=”true”时,表示该bean是抽象的bean,不能被初始化。


建议有时间有能力的同学读一下源码

导入已经转化好的的 Springframework.beans 项目

这里写图片描述

原创粉丝点击