前段时间回顾Spring的一些技术和信息,自己去试着配置框架进行练习,这里就分享一下Spring bean配置的各种标签方便自己去配置信息,
Spring官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/#mvc-controller
比较好的xml配置文档:http://book.51cto.com/art/201004/193746.htm
beans: 整个配置文件的根节点,包含一个或多个Bean元素。在该标记中可配置命名空间与schema的装载路径,还可以通过default-init-method属性为该配置文件中的所有Bean实例统一指定初始化方法,通过default-destroy-method属性为该配置文件中的所有Bean实例统一指定销毁方法,通过default-lazy-init属性为该配置文件中的所有Bean实例统一指定是否进行迟延加载
bean标记:
用该标记定义一个Bean的实例化信息,用以指导Bean工厂正确地进行Bean的生产与装配。由class属性指定类全名,由id(推荐使用)或name属性指定生成的Bean实例名称。init-method属性指定初始化时要调用的方法,destroy-method属性实例销毁时要调用的方法。Bean实例的依赖关系可通过property子标记(set方式注入)或constructor-arg子标记(构造方式注入)来定义。bean标记中的scope属性用以设定Bean实例的生成方式,当scope设置为singleton或默认时以单例模式生成,当scope设置为prototype时则以原型(多例)模式生成。
constructor-arg标记:
它是bean标记的子标记,用以传入构造参数进行实例化,这也是注入依赖关系的一种常见方式。index属性指定构造参数的序号(从0开始),当只有一个构造参数是通常省略不写;type属性指定构造参数的类型,当为基本数据类型时亦可省略此属性;参数值可通过ref属性或value属性直接指定,也可以通过ref或value子标记指定
property:它是bean标记的子标记,用以调用Bean实例中的相关Set方法完成属性值的赋值,从而完成依赖关系的注入
name:知道bean实例的属性名称
ref属性或value属性直接指定,也可以通过ref或value子标记指定
ref标记:
该标记通常作为constructor-arg、property、list、set、entry等标记的子标记,由bean属性指定一
个Bean工厂中某个Bean实例的引用
value标记:该标记通常作为constructor-arg、property、list、set、entry等标记的子标记,用以直接指定一个常
量值
list标记:该标记用以封装List或数组类型属性的依赖注入(即赋值),具体的元素通过ref或value子标记
指定
set标记:该标记用以封装Set类型属性的依赖注入(即赋值),具体的元素通过ref或value子标记指定
map标记:标记用以封装Map类型属性的依赖注入(即赋值),具体的元素通过entry子标记指定
entry标记:该标记通常用做map标记的子标记,用以设置一个“键/值”对。key属性接收字符串类型的“键”名称,“值”则可由ref或value子标记指定
props标记:
该标记用以封装Properties类型属性的依赖注入(即赋值),具体的元素通过prop子标记指定
prop标记:该标记通常用做props标记的子标记,用以设置一个“键/值”对。key属性接收字符串类型的“键”名称,“值”则可放置在prop标记体内
null标记:该标记用于赋一个null值,与在Java中直接为某个属性赋null值效果等同
配置bean实例 :User的bean创建实例时加入了原型的作用域
<?xml version="1.0" encoding="UTF-8"?>
<!-- 最基本的命名空间定义和空间装载 -->
<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-2.5.xsd">
<!-- 创建 SimpleDateFormat 实例并对这个实例进行实例化-->
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
<!-- 对构造参数进行实例化 -->
<constructor-arg value="yyyy年MM月dd hh时mm分ss秒"/>
</bean>
<!-- 创建User 类的实例 并对实例的属性进行赋值 作用域是原型 不设置 scope 时作用域是 单例 -->
<bean id="user" class="test.spring.bean.User">
<property name="name" value="小明"/>
<property name="password" value="123456"/>
</bean>
<!-- 创建Data实例: -->
<bean id="data" class="java.util.Date"></bean>
<!-- 创建 test.spring.bean.XmlIocBean bean的实例 init-method初始化,相当与调用了init方法 destroy-method销毁的方法: -->
<bean id="xmlIocBean" class="test.spring.bean.XmlIocBean"
init-method="myInit" destroy-method="myDestroy">
<!-- constructor-arg标记用以传入构造参数进行实例化 index 是从构造器传参的顺序 0开始 type:参数的类型 ref赋值: -->
<constructor-arg index="0" type="java.text.SimpleDateFormat" ref="simpleDateFormat"/>
<constructor-arg index="1" type="java.util.Date" ref="data"></constructor-arg>
<!-- bean 中的属性进行赋值 intnumber 数组-->
<property name="intnumber">
<list>
<value>2</value>
<value>15</value>
<value>7</value>
</list>
</property>
<!-- list 属性赋值: 赋值bean对象-->
<property name="list">
<list>
<ref bean="user"/>
<ref bean="user"/>
</list>
</property>
<!-- Set 属性赋值: 赋值bean对象-->
<property name="set">
<set>
<ref bean="user"/>
<ref bean="user"/>
</set>
</property>
<!-- Map 属性赋值:key是直接赋值 value key2是ref bean赋值一个类的实例 -->
<property name="map">
<map>
<entry key="key1">
<value>key1元素的值</value>
</entry>
<entry key="key2">
<ref bean="user"></ref>
</entry>
</map>
</property>
<!-- 对象创建实例化,并进行赋值 -->
<property name="props">
<props>
<prop key="prop1">properties元素1 </prop>
<prop key="prop2">properties元素2 </prop>
</props>
</property>
</bean>
</beans>
这里出现过问题:
User类中,我当时创建构造器,的时候传了参数,那么在配置文件中必须要为构造函数赋值:
创建 simpleDateFormat 的实例bean的时候,我打算给他property标记使用赋值,这个是当前实例bean中的属性进行赋值,不是实现化赋值,<constructor-arg value="yyyy年MM月dd hh时mm分ss秒"/>给当前bean进行实例化
这里是Spring xml的Bean的配置,这样很麻烦要自己手动去装配,所以Spring 声明了基于注解的方式去进行Bean的自动装配
基于Annotation方式的Bean装配:
在Spring中尽管使用XML配置文件可以完成所有的配置工作,直观表达Java EE程序员的"装配意图",但如果应用中Bean数量成千上万的话,最终会导致XML配置文件体积剧增,面对臃肿的XML配置文件,给维护与升级带来一定的困难。
伟大的Spring开发团队想到了JDK 1.5提供的新特性--Annotation注释技术:
了解了Annotation注释的工作原理之后,方觉得真正伟大的不是Annotation注释本身,而是幕后默默无闻地进行注释处理的Annotation处理器
Annotation处理器是基于JDK的反射机制来实现的,Spring 2.5中定义的一系列Annotation注释
Spring 2.5中常用的Annotation注释说明:
@Autowired:通过@Autowired注解对Bean的属性变量、属性的Setter方法及构造函数进行标注,配合对应的注解处理器AutowiredAnnotationBeanProcessor完成Bean的自动配置工作。
@Autowired注解默认是按Bean类型进行装配的,也就是说注解处理器AutowiredAnnotationBeanProcessor会在Spring容器中寻找与@Autowired注解所在属性同类型的Bean实例进行装配,如果找到多个满足条件的Bean实例时,将会抛出NoSuchBeanDefinitionException异常。
@Autowired注解加上@Qualifier注解的话,可以直接指定一个Bean实例名称来进行装配。
@Resource:@Resource的作用相当于@Autowired,配合对应的注解处理器CommonAnnotationBeanPostProcessor完成Bean的自动配置工作。
只不过@Autowired注解默认是按Bean类型进行装配的,而@Resource注解默认是按Bean实例名称进行装配罢了
@Resource有两个属性是比较重要的,分别是name和type。Spring将@Resource注解的name属性解析为Bean实例的名字,而type属性则解析为Bean实例的类型
@Qualifier:如果@Autowired注解加上@Qualifier注解的话,可以将默认按Bean类型进行装配变换为按Bean实例名称进行装配,具体的Bean实例名称由@Qualifier注解的参数指定
@PostConstruct:在Bean中的某个方法上加上@PostConstruct注解,则该方法将会在Bean初始化之后被Spring容器调用,作用等同在Spring配置文件中为bean标签指定init-method属性
@PreDestroy:在Bean中的某个方法上加上@PreDestroy注解,则该方法将会在Bean实例被销毁之前由Spring容器进行调用,作用等同在Spring配置文件中为bean标签指定destroy-method属性
在Java EE中启用Spring的注解装配通常需要经过以下几个步骤。:
(1)导入Spring注解装配功能所依赖的JAR包Jcommon-annotations.jar,并将其加入到当前项目的classpath中来,该文件在spring-framework-2.5.6\spring-framework-2.5.6 \lib\j2ee文件夹下可以找到
在Spring配置文件中定义context命名空间与相应的schemaLocation:
- <?xml version="1.0" encoding="UTF-8"?>
- <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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context-2.5.xsd">
- </beans>
(3)在Spring配置文件中开启相应的注解处理器:
- <!-- 开启注解处理器 -->
- <context:annotation-config/>
(4)在Bean中使用表6-4中列举的Annotation注释进行Bean属性的自动装配。
这个好处是使用了注解对bean的实例进行了自动装配,不需要在创建bean实例中使用property标记进行对象的装配,但必须要进行创建bean,要在xml中配置开启注解处理器,才能使用注解的功能
http://www.springframework.org/schema/context-->注解装配功能
<?xml version="1.0" encoding="UTF-8"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 开启注解出来器,这个spring文件中所有的注解能进行使用 -->
<context:annotation-config/>
<!-- 通过构造方法注入属性值装配SimpleDateFormat单实例 创建bean-->
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
<!-- 构造函数赋值 -->
<constructor-arg value="yyyy年MM月dd hh时mm分ss秒"/>
</bean>
<!-- 创建date实例 -->
<bean id="now" class="java.util.Date"/>
<!-- 创建User实例 我们已经是使用了注解,所以不需要自动装配 原型模式 每次调用时都会生成一个全新的User实例-->
<bean id="user" class="test.spring.bean.User" scope="prototype"/>
<!-- 创建 random 实例 单例-->
<bean id="random" class="java.util.Random"/>
<!-- 使用单例模式装配XmlIocBean实例, 实例属性通过Annotation注解方式注入 -->
<bean id="annotationIocBean" class="test.spring.bean.AnnotationIocBean" />
</beans>
因为这里没有使用注解扫描,所有要使用的类都要在这里使用bean来创建实例化,
这里只使用了开启注解处理器,用到了自动装配的功能。
这里就是全部的Spring Bean的装配的方式,这应该就是Spring IOC和DI的实现方式,所以bean的创建教给Spring,要使用就去拿就行了,不的不说Spring还是很强大的