Spring 基础知识 (二)
1.1、Spring的基本配置
在上一篇文章中简单介绍了Spring的作用和基本用法,接下来看一下Spring的基本配置。
在bean元素中id和name的区别
<bean id|name="name" class="classname" ></bean>
在Spring配置中,id和name属性都可以定义bean元素的名称,不同的是:
id属性,遵守XML语法ID约束。必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号,不能以“/”开头。
name属性,就可以使用很多特殊字符,比如在Spring和Spring MVC的整合中,就需要使用name属性来的定义bean的名称。
<bean name="/login" class="xxxAction" />
这里需要注意:从Spring3.1开始,id属性不再是ID类型了,而是String类型,也就是说id属性也可以使用“/”开头了,而bean元素的id的唯一性由容器负责检查。
<bean id="/login" class="xxxAction" />
当然也使用name属性为<bean/>
元素起多个别名,多个别名之间使用逗号或空格隔开,在代码中依然使用BeanFactory对象.getBean(…)方法获取。
<bean name="hello,hi" class="classname"/>
或者 <bean name="hello hi" class="classname"/>
在Spring中添加其他配置文件
随着应用规模的增加,系统中<bean>
元素配置的数量也会大量增加,导致applicationContext.xml配置文件变得非常臃肿。
为了避免applicationContext.xml文件过于庞大、臃肿,为提高其可读性,可以将一个applicationContext.xml文件分解成多个配置文件,然后在applicationContext.xml文件中包含其他配置文件即可。
使用import元素引入其他的配置文件:
<import resource="applicationContext-service.xml" />
使用import元素注意:
1、默认情况下,从classpath的跟路径寻找。
2、可以使用前缀来定位文件的基础位置:
①:[classpath:]:后面的文件从classpath路径开始找;
<import resource="classpath:applicationContext-service.xml" />
②:[file:]:后面的文件使用文件系统的路径开始找;
<import resource="file:D:/Project/src/main/resources/applicationContext-service.xml" />
配置bean懒加载
<beans default-lazy-init="default | false | true"> 针对所有的bean都起效
<bean lazy-init="default | false | true"> 针对单个bean起效
配置bean作用域
<bean id="" class="全限定名" scope="作用域"/>
singleton: 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认)
prototype: 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean():不会在容器启动时创建对象
request: 用于web开发,将Bean放入request范围 ,request.setAttribute(“xxx”) , 在同一个request 获得同一个Bean
session: 用于web开发,将Bean 放入Session范围,在同一个Session 获得同一个Bean
globalSession: 一般用于Porlet应用环境 , 分布式系统存在全局session概念(单点登录),如果 不是porlet环境,globalSession 等同于Session ;
在开发中主要使用 scope=“singleton”、 scope=“prototype” ;
对于Struts2中的Action使用prototype类型,其他使用singleton 。
配置bean初始化和销毁方法
比如DataSource,SessionFactory最终都需要关闭资源:在Bean销毁之前,都要调用close方法.
<bean id="someBean" class="全限定名" init-method="该类中初始化方法名" destroy-method="该类中销毁方法名">
如果bean的scope=“prototype”,那么容器只负责创建和初始化,它并不会被spring容器管理。交给用户自己调用.
配置bean自动注入方式
<bean id="somebean" class="SomeBean全限定名" autowire="byType"/>
autowire 属性:让spring按照一定的方式自己去找合适的对象,并完成DI
- default:不要自动注入
- no:不要自动注入
- byName:按照名字注入((按照属性的名字在spring中找bean) factory.getBean(“属性的名字”))
- byType:按照依赖对象的类型注入(factory.getBean(属性的类型))
- constructor:按照对象的构造器上面的参数类型注入
注意:
1,如果按照byName自动注入,要求所有的属性名字和id的名字必须保证一种规范的命名方式;
2,如果按照byType注入,如果spring中同一个类型有多个实例–>报bean不是唯一类型错误;
配置bean属性注入
使用setter注入:
1,使用bean元素的**<property>
**子元素设置;
1),简单类型值,直接使用value赋值;
2),引用类型,使用ref赋值;
3),集合类型,直接使用对应的集合类型元素即可。
2,spring通过属性的setter方法注入值;
3,在配置文件中配置的值都是string,spring可以自动的完成类型的转换
4,属性的设置值是在init方法执行之前完成的
<bean id="helloword" class="SpringDemo.HelloWorld" >
<property name="name" value="zhangsan"/>
<!--list-->
<property name="list">
<list>
<value>a</value>
<value>b</value>
<value>c</value>
</list>
</property>
<!--数组-->
<property name="array">
<array>
<value>as</value>
<value>ab</value>
</array>
</property>
<!--map-->
<property name="map">
<map>
<entry key="a" value="b"></entry>
</map>
</property>
<!--Properties-->
<property name="pro">
<props>
<prop key="prop1">a</prop>
</props>
</property>
</bean>
使用构造器注入:
<bean id="somebean" class="spring.SomeBean">
<!-- constructor-arg:构造器参数
1,spring在实例化对象的时候,如果对象没有配置constructor-arg,则使用默认的构造器实例化对象
2,如果有constructor-arg,那么spring使用这些constructor-arg来唯一确定一个构造器
-->
<constructor-arg value="name"/>
<constructor-arg value="123"/>
<constructor-arg ref="otherbean"/>
</bean>
1,默认情况下,constructor-arg的顺序就是构造器参数的顺序
调整构造器顺序:
1.index:在构造器中的参数位置
2.type:在构造器中的参数的类型
3.name:在构造器中按照构造器的参数名字设置值
1.2、Spring的自动装配
在Spring中除了通过getBean来获取bean,还可以通过其他方法,那就是自动装配。
spring中通过注解的方式完成自动装配:
方式一:通过spring自带的标签来完成Autowired和Qualifier标签:
方式二:通过javaEE自带的标签来完成@Resource
@Autowired和@Qualifier标签 :
为了体验自动装配,需要让Spring来管理测试代码,所以需要用到Spring的测试。
@RunWith(SpringJUnit4ClassRunner.class)//让测试运行于Spring测试环境
@ContextConfiguration("classpath:applicationContext.xml")//Spring配置文件所在位置
public class SpringTest {
@Autowired
HelloWorld helloword;
@Test
public void TestIoC(){
helloword.hello();
}
}
1.通过@Autowired标签可以让Spring自动的把属性需要的对象找出来,并注入给该属性。
2.在使用@Autowired时,首先在容器中查询对应类型的bean
如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据
如果查询的结果不止一个,那么@Autowired会根据名称来查找。
如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false
3.@Autowired标签贴在字段或者setter方法上。
4.@Autowired可以同时为一个属性注入多个对象。
public void setXxx(OtherBean1 other1,OtherBean2 other2) {}
5.使用@Autowired标签可以注入Spring内置的重要对象,比如BeanFactory,ApplicationContext。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {
@Autowired
private ApplicationContext ctx;
}
6.默认情况下@Autowired标签必须要能找到对应的对象,否则报错。不过,可使用required=false来避免该问题:@Autowired(required=false)
7.@Autowired找bean的方式:
1)、首先按照依赖对象的类型找,如果找到则使用setter方法或者字段直接注入;
2)、如果在Spring上下文中找到多个匹配的类型,再按照名字去找,如果没有匹配则报错;
3)、可以通过使用@Qualifier(“otherBean”)标签来规定依赖对象按照bean的id+类型去找;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Autowired
@Qualifier("helloword")
HelloWorld helloword;
@Test
public void TestIoC(){
helloword.hello();
}
}
@Resource标签 :
1,@Resource标签是JavaEE规范的标签;
2,@Resource标签也可以作用于字段或者setter方法;
3,也可以使用@Resource标签注入一些Spring内置的重要对象,比如BeanFactory.ApplicationContext;
4,@Resource必须要求有匹配的对象;
5,@Resource标签找bean的方式:
1),首先按照名字去找,如果找到,就使用setter或者字段注入;
2),如果按照名字找不到,再按照类型去找,但如果找到多个匹配类型,报错;
3),可以直接使用name属性指定bean的名称;但是,如果指定的name,就只能按照name去找,如果找不到,就不会再按照类型去找;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringTest {
@Resource(name = "helloword")
HelloWorld helloword;
@Test
public void TestIoC(){
helloword.hello();
}
}