重新温习spring-bean的创建

  使用spring进行web开发很长时间了,但对于spring中原理的东西一直都很模糊,只是当初在学习spring的时候看过spring的源码,但现在已经记不清了,只记得依赖注入和AOP。

  spring通过应用上下文(Application context)装载bean并且把他们组装起来。应用上下文是基于BeanFactory派生出来的,包括了BeanFactory的所有功能,除非有特殊情况,一般推荐使用应用上下文。BeanFactory使用的是延迟加载,只有当应用使用到这个bean是,才会进行创建,而Application Context是在spring启动的时候进行对bean进行创建,便于发现bean的错误。

  加载Application Context三种经常用到的实现:  

  1. ClassPathXmlApplicationContext:从类路径中加载。
  2. FileSystemXmlApplicationContext:从文件系统加载。
  3. XmlWebApplicationContext:从web系统中加载。

  使用应用上下文配置bean,在xml中使用bean标签进行配置,id是这个bean的id,class是这个bean的对象路径,scope是bean的作用域(singleton,prototype,request,session,global-session)说明见下图:

init-method初始化bean时调用的方法destroy-method销毁bean时调用的方法,创建和销毁的方法也可以在beans标签的default-init-method和default-destroy-method统一定义.

如果使用的是应用上下文配置的bean,在加载xml时就会调用初始化方法,在关闭Application Context时就会调用销毁方法。

在xml中配置如下:

<bean id="tom" class="com.my.study.Student" init-method="initMethod" destroy-method="destoryMethod">
    <property name="id" value="10001"/>
    <property name="name" value="tom"/>
    <property name="age" value="15"/>
    <property name="grade" value="1"/>
</bean>

 

统一配置方法初始化和销毁方法如下:
<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.xsd"
        default-init-method="initMethod1" default-destroy-method="destoryMethod1">
测试发现如果在beans和bean都配置初始化和销毁方法,spring会执行bean里配置的方法。
如果在beans标签中配置的方法在bean中没有定义,在spring启动时不会报错,如果在bean标签中配置的方法在bean中没有定义,则在spring启动时会报错。



bean标签可以注入其他bean:
 <bean id="jerry" class="com.my.study.Teacher">
        <property name="id" value="200001"></property>
        <property name="name" value="jerry"></property>
    </bean>
    <bean id="tom" class="com.my.study.Student" init-method="initMethod" destroy-method="destoryMethod">
        <property name="id" value="10001"/>
        <property name="name" value="tom"/>
        <property name="age" value="15"/>
        <property name="grade" value="1"/>
        <property name="teacher" ref="jerry"></property>
    </bean>
</beans>

 

bean标签里可以使用property标签对bean中的属性进行注入,不仅仅可以注入基础的数值,还可以注入list,map等其他集合,

这个是map中entry的属性字段:

注入list的方式如下:

<bean id="tom" class="com.my.study.Student" init-method="initMethod" destroy-method="destoryMethod">
        <property name="id" value="10001"/>
        <property name="name" value="tom"/>
        <property name="age" value="15"/>
        <property name="grade" value="1"/>
        <property name="teacher" ref="jerry"></property>
        <property name="subjectList">
            <list>
                <value>"语文"</value>
                <value>"数学"</value>
            </list>
        </property>
    </bean>

 当然list下面也可以选择ref注入其他bean,set的方式和list一样。

map的注入方式如下:

 <bean id="jerry" class="com.my.study.Teacher">
        <property name="id" value="200001"></property>
        <property name="name" value="jerry"></property>
    </bean>
    <bean id="tom" class="com.my.study.Student" init-method="initMethod" destroy-method="destoryMethod">
        <property name="id" value="10001"/>
        <property name="name" value="tom"/>
        <property name="age" value="15"/>
        <property name="grade" value="1"/>
        <property name="teacher" ref="jerry"></property>
        <property name="subjectList">
            <list>
                <value>"语文"</value>
                <value>"数学"</value>
            </list>
        </property>
        <property name="teacherSubject">
            <map>
                <entry key="语文" value-ref="jerry"/>
            </map>
        </property>
    </bean>

 

最后再加个知识点,SpEL表达式:

简单SpEL表达式是对字面上的值,bean的某个属性或者某个类的常量进行求值

字面值

<property name="age" value="#{15}"/>

 bean的某个属性

<entry key="#{jerry.name}" value-ref="jerry"/>

 bean

<entry key="语文" value="#{jerry}"/>

 这里引入bean是就不需要用ref-value,如果用SpEL只需要使用value即可

SpEL表达式可以使用?.替代.来防止出现空指针异常。

<entry key="#{jerry.getName().toUpperCase()}" value-ref="jerry"/>

 这里如果jerry.getName()为空则会出现空指针异常。可以使用?.如果前面的方法返回为NULL时,就不会执行后面的方法。

<entry key="#{jerry.getName()?.toUpperCase()}" value-ref="jerry"/>

 操作类

<property name="age" value="#{T(java.lang.Math).random()}"/>

 这里T()返回的是java.lang.Math的对象

SpEL操作运算

比较运算符

逻辑运算符

条件表达式

正则表达式

SpEL表达式还可以访问集合这里就不过多介绍。可以查看《spring实战第三版》第二章P58查看详细的。

 

 

 

 

 

 

 

 

 

 

上面使用到的截图是从《spring实战第三版》中截取,后面会继续完善。

 

posted @ 2018-01-08 14:40  小小小怪兽  阅读(235)  评论(0编辑  收藏  举报