Spring语法总结
Spring语法总结
文章的目的是,简明扼要,在需要了解Spring语法时能够快速了解。
配置bean
配置形式:基于XML文件的方式
xml中bean的编写方式:
<bean id="helloword" class="com.zhy.spring.helloworld">
<property name="name" value="Spring"></property>
<bean>
其中 id是指要创建的对象名,通过id可以获取bean且id值一定是唯一的,class为bean的全类名(即类的路径),可以看出这里利用了反射。
name是指id所指代的类里面的setName()方法,value就是传进方法的值
需要注意的是: 1.这种方法要求bean中必须含有无参构造器。
2.若name改为name2,则是指代setName2()方法;
bean的获取方式:
//1.创建Spring的IOC容器对象
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//引号里的是xml文件的名称
//2.从IOC容器中获取Bean的实例
HelloWorld helloworld = (HelloWorld)ctx.getBean("helloword");//引号内是bean中的id值
在上述IOC容器获取Bean的实例的方法,是通过id来获取bean的,除了这种方式,还可以通过类的方式来获取bean(即xml中的class值),如下:
HelloWorld helloworld = ctx.getBean(HelloWorld.class);
可以看见,这种方式是不需要进行强制类型转换的,因为在括号中就已经声明了类型。但是显而易见,这种方法有一个很大的问题,就是当多个bean同类型(即多个bean的class相同)时,无法判断适用那个bean,这时这个方法将不再适用。
依赖注入的方式:属性注入、构造方法注入
属性注入
- 属性注入即通过setter方法注入Bean的属性值或依赖的对象
- 属性注入使用< property >元素,适用name属性指定Bean的属性名称,value属性或< value >子节点指定属性值
- 属性注入是实际应用中最常用的注入方式
如下,
<bean id="helloword" class="com.zhy.spring.helloworld">
<property name="name" value="Spring"></property>
<bean>
构造方法注入
- 通过构造方法注入Bean属性值或依赖的对象,它保证了Bean实例在实例化后就可以使用
- 构造器注入在< constructor-arg >元素里声明属性
- < constructor-arg >中没有name属性
<bean id="car" class="com.zhy.spring.car">
<constructor-arg value ="20" index=0 type="int">
<constructor-arg value ="awm" index=1 type="string"></constructor-arg>
<constructor-arg type="int">
<value>240</value>
</constructor-arg>
<bean>
其中,value 指传入setter方法中的值,可以通过index来按顺序传入值,type可以用来解决构造器id相同,且constructor-arg的数量相同的情况,即根据type来选择正确的传入值。
如果字面值,即value 中若是有特殊字符,使用<![CDATA[]]>包裹起来
当组成引用程序的Bean经常需要相互协作以完成应用程序的功能,要使Bean能够互相引用,就必须在Bean配置文件中指定Bean的应用,在 Bean配置文件中可以通过< ref >元素或ref属性为Bean的属性或构造器参数指定对Bean的作用,如下:
<bean id="person" class="com.zhy.spring.person">
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="car" ref="car"></property>
<bean>
< ref > 元素
<bean id="person" class="com.zhy.spring.person">
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="car" >
<ref>car</ref>
</property>
<bean>
也可以在属性或构造器里包含Bean的声明,这样的Bean称为内部Bean,如下:
<bean id="person" class="com.zhy.spring.person">
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="car" >
<bean class="com.zhy.spring.car">
<constructor value="Ford"></constructor-arg>
<constructor value="Changan"></constructor-arg>
<constructor value="200000" ></constructor-arg>
</bean>
</property>
<bean>
其实这就是在Bean内部进行的一个Bean的声明
当属性是集合类型时,如何为这个集合属性赋值呢,如下:
<bean id="person" class="com.zhy.spring.person">
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="car" >
<list>
<ref bean="car"></ref>
<ref bean="car2"></ref>
</list>
</property>
<bean>
上述代码中list范型为car类型
为map赋值,利用map结点及map的entry子节点配置map类型的成员变量
<bean id="person" class="com.zhy.spring.person">
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="cars" >
<map>
<entry key="AA" value-ref="car"></entry>
<entry key="BB" value-ref="car2"></entry>
</map>
</property>
<bean>
为< propos >定义java.util.Properties,该标签使用多个< prop >作为子标签,每个< prop >标签必须定义key属性
使用props 和prop 子节点来为Properties 属性赋值
一次性为集合赋值
<util:list id="cars">
<ref bean="car">
<ref bean="car2">
</util:list>
<bean id="person" class="com.zhy.spring.person">
<property name="name" value="tom"></property>
<property name="age" value="20"></property>
<property name="cars" ref="cars"></property>
<bean>
感觉就是创建一个集合,然后命名,这样以后就可以直接通过名字来获取集合中的内容
通过P命名空间为 Bean的属性赋值,事先需要先导入p命名空间(p命名空间是在spring2.5后开始引用的),如下:
<bean id ="person" class="com.zhy.spring.person" p:age="30" p:name="Queen" p:cars-ref="cars">
</bean>
自动装配
可以使用autoWire属性指定自动装配的方式
byName,根据Bean的名字和当前bean的setter风格的属性名进行自动装配,若有匹配的,则进行自动装配,若没有匹配的,则不装配
<bean id="person" class="com.zhy.spring.person" p:name="tom" autowire="byName"></bean>
byType,根据Bean的类型和当前bean的属性类型进行装配,庹IOC容器中有1个以上的类型匹配的bean,则抛异常
缺点:
- autowire是使用在bean中的,所以一旦使用autowire,所有的引用属性就都必须使用autowire来自动装配,不够灵活
- autowire只能选择为byName或者byType,不能同时选择,不够灵活
bean之间的关系:继承,依赖
继承
bean配置的继承:使用bean的parent属性指定继承那个bean的配置,如下:
<bean id="address" class="com.zhy.spring.address" p:city="ChengDu> p:street="ChunXiLu"></bean>
<bean id="address2" p:street="KuanZaiXiangZi" parent="address"></bean>
- 子Bean从父Bean中继承配置,包括Bean的属性配置
- 子Bean也可以覆盖从父Bean继承过来的配置
- 父Bean可以是一个实例也可以是一个配置模板。上述就是实例的父Bean,加上属性abstract="true"就是配置模板,这样的父Bean将不会被Spring实例化。另外,若一个Bean的class属性没有指定,则必须是一个模板Bean(抽象Bean)
- 并不是Bean中所有属性都可以,例如 abstract和autowire不能继承
依赖
<bean id="person" class="com.zhy.spring.person" p:name="tom" p:address-ref="address2" depends-on="car"></bean>
依赖的意思就是当前Bean创建之前必须有依赖的Bean,被依赖的Bean会在本Bean实例化之前创建好;
如果前置依赖于多个Bean,则可以通过逗号,空格的方式配置Bean的名称
Bean的作用域
使用Bean的scope属性来配置Bean的作用域
- singgleton:默认值。容器初始时(ApplicationContext ctx = new ClassPathXmlApplicationContext(“bean.xml”))创建Bean实例。在整个容器的生命周期内只创建这一个Bean。即单例的;
- prototype:原型。容器初始化时不创建Bean的实例,而在每次请求时都创建一个新的Bean实例,并返回。
<bean id="helloword" class="com.zhy.spring.helloworld" scope="prototype">
<property name="name" value="Spring"></property>
<bean>
使用外部属性文件
在配置文件中配置Bean时,有事需要在Bean的配置里混入系统部署的细节信息(例如:数据源配置信息、文件路径等)而这些部署细节实际上需要和Bean配置相分离。
- Spring提供了一个PropertyPlaceholderConfigure的BeanFactory后置处理器,这个处理器允许用户将Bean配置的部分内容外衣到属性文件中,可以在Bean配置文件中使用形式为${var}的变量。PropertyPlaceholderConfigurer从属性文件里加载属性,并使用属性来替换变量。
- Spring还允许在属性文件中使用${propName},以实现属性之间的相互引用。
属性文件:
Bean的写法:
- 需要注意的是 需要先导入属性文件
Spring表达式语言:SpEL
用法概念:
综合运用:
IOC容器中Bean的生命周期方法
SpringIOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务。
Spring IOC容器对Bean的生命周期进行管理的过程:
-
通过构造器或工厂方法创建Bean实例
-
为Bean的属性设置值和对其他Bean的引用
-
调用Bean的初始化方法
-
Bean可以使用了
-
当容器关闭时,调用Bean的
在Bean的声明里设置init-method和destroy-method属性,为Bean指定初始化和销毁方法
创建Bean后置处理器 -
Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理
-
Bean后置处理器对 IOC容器里的所有的 Bean实例逐一处理,而非单一实例
-
对Bean后置处理器而言,需要实现接口(Interface BeanPostProcessor),在初始化方法被调用前后,Spring将把每个Bean实例分别传递给上述接口的一下两个方法:postProcessAfterInitializetion(Object bean,String beanName)、postProcessBeforeInitialization(Object bean,String beanName)
配置Bean:通过工厂方法、FactoryBean、注解
通过工厂方法配置Bean
通过调用静态工厂方法来创建Bean
通过StaticCarFactory的静态方法来返回的实例。
通过调用实例工厂方法
通过FactoryBean来配合Bean
基于注解的方式配置Bean