了解完Spring的基本概念后,我们紧接着来了解Spring中的核心文件--Spring配置文件。
我们在上一节Spring的基本概念中快速使用了一下Spring,其中我们在配置文件中主要涉及到就是Bean标签的配置:主要的配置字段有id, class, scope。 id是Bean的唯一标识不可重复,class是该类的全限定名。scope则是影响范围,有singleton和prototype两个可选项。当选择为singleton时,表示每次问IoC容器索要的对象是同一个,而选择为prototype时,则生成的对象是不同的。读者可分别打印其地址尝试。
<!--
bean:将对象交给IOC容器来管理
属性:
id:bean的唯一标识,不能重复
class:设置bean对象所对应的类型
-->
<bean id="hello-world" class="com.bylearning.spring.pojo.HelloWorld" scope="prototype"/>
此外,scope不同时,对象的创建时机不同,我们可以覆盖构造方法观察构造方法中的输出语句何时打印。?
public class HelloWorld {
public HelloWorld() {
// 覆盖无参构造方法,是为了验证bean的scope分别为singleton和prototype时,创建对象的时机
// 在Test代码中获取IoC容器那一行代码中打断点,执行测试方法
// 当scope=singleton时,IoC容器完成加载时,对象就创建了
// 当scope=prototype时,IoC容器完成加载时,还未创建对象,而是调用getBean方法时创建的
System.out.println("object is creating...");
}
public void sayHello() {
System.out.println("hello, spring");
}
}
谈到构造方法,我们在Spring基本概念中也提到了,Spring容器创建对象的方式是反射。而反射通常是通过无参构造方法实现的,而一个类会自动生成一个默认的无参构造方法。说到这里,已经有一些开发经验的伙伴是否有这样的经历:为一个类创建了一个有参构造方法,此时我们向Spring容器索要对象时提示错误:
因为此时找不到无参的构造方法了,反射创建对象就失败了。包括配置文件也会提醒你:没有合适的构造方法。
此外,还能在配置文件中配置对象的初始化/销毁方法,属性是:init-method/destory-method。由于不常用,我们不再举例。
想象这样一个场景,我们上面的HelloWorld类中有一个成员属性是HelloSpring对象,我们怎么给HelloWorld对象设置这样的一个成员属性对象呢?这需要使用到依赖注入(Dependency Injection,DI),是Spring给对象设置成员变量的方法。有两种实现方式:构造方法和set方法。
HelloWorld类中添加成员对象与包含该属性的有参构造
public class HelloWorld {
private HelloSpring helloSpring;
public HelloWorld(HelloSpring helloSpring) {
this.helloSpring = helloSpring;
}
public void sayHello() {
helloSpring.sayHello();
}
}
并在配置文件中添加HelloSpring Bean标签,添加使用构造方法注入helloSpring属性的一行标签
<bean id="hello-spring" class="com.bylearning.spring.pojo.HelloSpring" />
<bean id="hello-world" class="com.bylearning.spring.pojo.HelloWorld" scope="prototype">
<constructor-arg name="helloSpring" ref="hello-spring"></constructor-arg>
</bean>
同样添加成员对象与该属性的set方法
public class HelloWorld {
private HelloSpring helloSpring;
public void sayHello() {
helloSpring.sayHello();
}
public void setHelloSpring(HelloSpring helloSpring) {
this.helloSpring = helloSpring;
}
}
添加使用set方法注入属性的一行标签
<bean id="hello-spring" class="com.bylearning.spring.pojo.HelloSpring" />
<bean id="hello-world" class="com.bylearning.spring.pojo.HelloWorld" scope="prototype">
<property name="helloSpring" ref="hello-spring"></property>
</bean>
我们注意到这里引用其它对象作为成员变量时,用的关键字是"ref",实际上这里有其它选项:当需要注入的是普通属性如int, float时,应使用"value"关键字;要注入集合属性时,使用"list";要注入map时,使用"map"。这些细碎的知识,大家可以等到使用时去搜索一下,不要硬记,抓大放小,主要是理解大的思想。
可以想象,当项目的功能逐渐增加时,配置文件会变得异常庞大。此时我们可以分模块开发,将配置文件进行拆分。而在主配置文件里使用import标签引入其它配置文件。
<import resource="applicationContext-user.xml"></import>
<import resource="applicationContext-order.xml"></import>