此篇博文和上一篇博文有一些关联,如已经新建好的各种类的位置,如果对于类的位置不清楚请看上一篇博文
【Spring 4.0】Spring入门之第一个程序HelloWorld实现
**IOC(Inversion of Control)控制反转:**其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式
DI(Dependency Injection)依赖注入: IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接。
HelloWorld
的JavaBean(如果按照上一篇博文过来的朋友则不用做Bean的配置了,只需看一下解释就好。因为我是以上一篇的HelloWorld实例来讲解的)
public class HelloWorld {
private String user;
public HelloWorld() {
System.out.println("HelloWorld's constructor...");
}
public void setUser(String user) {
System.out.println("setUser:" + user);
this.user = user;
}
public HelloWorld(String user) {
this.user = user;
}
public void hello(){
System.out.println("Hello: " + user);
}
}
applicationContext
中为Bean中的属性赋值<bean id="helloWorld" class="com.spring.helloworld.HelloWorld">
<property name="user" value="Jerry">property>
bean>
属性 | 属性值 |
---|---|
class | bean 的 指的是HelloWorld的全路径名称,并且由于是通过反射方式创建Bean,因此Bean中必须有无参的构造器。如果没有无参构造器则会出错,当然如果没有显示声明构造器也无妨,因为虚拟机会隐式创建一个无参的构造器。 |
id | 当创建好一个bean之后,如何引用这个bean呢?就需要使用id.它标识bean.并且id唯一。id:Bean 的名称:(1)在 IOC 容器中必须是唯一的。(2)若 id 没有指定,Spring 自动将权限定性类名作为 Bean 的名字。(3)id 可以指定多个名字,名字之间可用逗号、分号、或空格分隔。 |
Main.java
中通过容器读出数据//1. 创建 Spring 的 IOC 容器
//ApplicationContext:代表IOC容器
//ClassPathXmlApplicationContext:是ApplicationContext接口的实现类
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 从 IOC 容器中获取 bean 的实例
HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");
//根据类型来获取 bean 的实例: 要求在 IOC 容器中只有一个与之类型匹配的 bean, 若有多个则会抛出异常.
//一般情况下, 该方法可用, 因为一般情况下, 在一个 IOC 容器中一个类型对应的 bean 也只有一个.
// HelloWorld helloWorld1 = ctx.getBean(HelloWorld.class);
//3. 使用 bean
helloWorld.hello();
在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用。
在Spring中,支持三种依赖注入的方式
<bean id="helloWorld2" class="com.spring.helloworld.HelloWorld">
<property name="user" value="Tom">property>
bean>
元素, 使用 name
属性指定 Bean 的属性名称,value
属性或 子节点指定属性值public class Car {
private String company;
private String brand;
private int maxSpeed;
private float price;
public Car(String company, String brand, float price) {
super();
this.company = company;
this.brand = brand;
this.price = price;
}
public Car(String company, String brand, int maxSpeed) {
super();
this.company = company;
this.brand = brand;
this.maxSpeed = maxSpeed;
}
public Car(String company, String brand, int maxSpeed, float price) {
super();
this.company = company;
this.brand = brand;
this.maxSpeed = maxSpeed;
this.price = price;
}
@Override
public String toString() {
return "Car [company=" + company + ", brand=" + brand + ", maxSpeed="
+ maxSpeed + ", price=" + price + "]";
}
}
<bean id="car" class="com.spring.helloworld.Car">
<constructor-arg value="KUGA" >constructor-arg>
<constructor-arg value="ChangAnFord" >constructor-arg>
<constructor-arg value="250000" >constructor-arg>
bean>
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car) ctx.getBean("car");
System.out.println(car);
上面的构造器只是为了其中的前三个属性进行初始化,bean中的配置其实是按照顺序来初始化的,当然如果构造器非常多,如何对bean进行配置呢?
public Car(String company, String brand, float price) {
super();
this.company = company;
this.brand = brand;
this.price = price;
}
public Car(String company, String brand, int maxSpeed) {
super();
this.company = company;
this.brand = brand;
this.maxSpeed = maxSpeed;
}
<bean id="car" class="com.spring.helloworld.Car">
<constructor-arg value="KUGA" index="1">constructor-arg>
<constructor-arg value="ChangAnFord" index="0">constructor-arg>
<constructor-arg value="250000" type="float">constructor-arg>
bean>
<bean id="car3" class="com.spring.helloworld.Car">
<constructor-arg value="BAOMA" type="java.lang.String">constructor-arg>
<constructor-arg value="ChangAnFord" type="java.lang.String">constructor-arg>
<constructor-arg value="250000" type="int">constructor-arg>
bean>
index
:
<constructor-arg value="BAOMA" type="java.lang.String">constructor-arg>
字面值:可用字符串表示的值,可以通过
元素标签或 value 属性进行注入。基本数据类型及其封装类、String 等类型都可以采取字面值注入的方式。若字面值中包含特殊字符,如有尖括号<>等等,可以使用 把字面值包裹起来。
<bean id="car2" class="com.spring.helloworld.Car">
<constructor-arg value="ChangAnMazda">constructor-arg>
<constructor-arg>
<value>]]>value>
constructor-arg>
<constructor-arg value="180" type="int">constructor-arg>
bean>
组成应用程序的 Bean 经常需要相互协作以完成应用程序的功能。要使 Bean 能够相互访问, 就必须在 Bean 配置文件中指定对 Bean 的引用。在 Bean 的配置文件中, 可以通过 元素或 ref 属性为 Bean 的属性或构造器参数指定对 Bean 的引用。也可以在属性或构造器里包含 Bean 的声明, 这样的 Bean 称为内部 Bean。
<bean id="dao5" class="com.spring.ref.Dao">bean>
<bean id="service" class="com.spring.ref.Service">
<property name="dao" ref="dao5">property>
bean>
当 Bean 实例仅仅给一个特定的属性使用时, 可以将其声明为内部 Bean. 内部 Bean 声明直接包含在
或
元素里, 不需要设置任何 id 或 name 属性。内部 Bean 不能使用在任何其他地方。
<bean id="service2" class="com.spring.ref.Service">
<property name="dao">
<bean class="com.spring.ref.Dao">
<property name="dataSource" value="c3p0">property>
bean>
property>
bean>
可以使用专用的
元素标签为 Bean 的字符串或其它对象类型的属性注入 null 值。
<bean id="dao2" class="com.spring.ref.Dao">
<property name="dataSource"><null/>property>
bean>
和 Struts、Hiberante 等框架一样,Spring 支持级联属性的配置。
<bean id="action" class="com.spring.ref.Action">
<property name="service" ref="service2">property>
<property name="service.dao.dataSource" value="DBCP2">property>
bean>
在 Spring中可以通过一组内置的 xml 标签(例如:
,
或 ) 来配置集合属性
java.util.List
类型的属性需要指定
标签, 在标签里包含一些元素. 这些标签可以通过
指定简单的常量值, 通过 指定对其他 Bean 的引用. 通过
指定内置 Bean 定义. 通过
指定空元素. 甚至可以内嵌其他集合。
<bean id="user" class="com.spring.helloworld.User">
<property name="userName" value="Jack">property>
<property name="cars">
<list>
<ref bean="car"/>
<ref bean="car2"/>
list>
property>
bean>
数组的定义和 List 一样, 都使用
java.util.Set
类型的属性java.util.Map
通过 标签定义,
标签里可以使用多个
作为子标签. 每个条目包含一个键和一个值。
<bean id="user7" class="com.spring.helloworld.User">
<property name="userName" value="Rose">property>
<property name="wifeName" value="JACK">property>
<property name="carmap">
<map>
<entry key="AA" value-ref="car">entry>
<entry key="BB" value-ref="car">entry>
map>
property>
bean>
标签里定义键
,
,
或
元素。
的属性定义: 简单常量使用key
和value
来定义; Bean 引用通过 key-ref
和 value-ref
属性定义。java.util.Properties
类型的属性 使用
定义java.util.Properties
, 该标签使用多个
作为子标签. 每个
标签必须定义key
属性.实际应用于配置数据库连接池。
import java.util.Properties;
public class DataSource {
private Properties properties;
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "DataSoure [properties=" + properties +"]" ;
}
}
<bean id="dataSource" class="com.spring.helloworld.DataSource">
<property name="properties" >
<props>
<prop key="user">routprop>
<prop key="password">routprop>
<prop key="jdbcUrl">jdbc:mysql://localhost/hibernateprop>
<prop key="driverClass">com.mysql.jdbc.Driverprop>
props>
property>
bean>
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
DataSoure[properties={driverClass=com.mysql.jdbc.Driver, user=rout, password=rout, jdbcUrl=jdbc:mysql://localhost/hibernate}]
utility scheme
定义集合 使用基本的集合标签定义集合时, 不能将集合作为独立的 Bean 定义, 导致其他 Bean 无法引用该集合, 所以无法在不同 Bean 之间共享集合.。可以使用 util schema 里的集合标签定义独立的集合 Bean. 需要注意的是, 必须在
根元素里添加 util schema 定义。
util:list
声明集合类型的 bean
<util:list id="cars">
<ref bean="car"/>
<ref bean="car2"/>
util:list>
<bean id="user2" class="com.spring.helloworld.User">
<property name="userName" value="Rose">property>
<property name="cars" ref="cars">property>
bean>
为了简化 XML 文件的配置,越来越多的 XML 文件采用属性而非子元素配置信息。Spring 从 2.5 版本开始引入了一个新的 p 命名空间,可以通过
元素属性的方式配置 Bean 的属性。使用 p 命名空间后,基于 XML 的配置方式将进一步简化。
<bean id="user3" class="com.spring.helloworld.User"
p:cars-ref="cars" p:userName="Titannic">bean>