IOC:其思想是反转资源获取的方向。传统的资源查找方式要求组件向容器发起请求查找资源作为回应,容器适时的返回资源。而应用了 IOC 之后,则是容器主动地将资源推动给所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源,这种行为也称为查找的被动形式
通过 XML 文件方式配置 Bean(还有通过注解的方式,此处暂表明 XML 方式)
// 1. 创建HelloWorld类,提供setName()和hello()方法
public class HelloWorld {
private String name;
}
public void setName(String name) {
this.name = name;
}
public void hello(){
System.out.println("Hello: " + name);
}
}
// 在src下创建applicationContext.xml,并配置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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.sangyu"/>
<!-- 配置bean-->
<!-- id:bean的名称,且在IOC容器中必须是唯一的,若id没有指定,Spring自动类名作为bean的名字-->
<bean id="helloWorld" class="com.sangyu.test.HelloWorld"> <!-- class:全类名,通过反射在IOC容器中创建bean,所以要求Bean中必须有无参数的构造器-->
<!-- name: 对应HelloWorld类中setter方法;value对属性的赋值-->
<property name="name" value="Spring"></property>
</bean>
</beans>
// 创建Main类,通过容器调用HelloWorld类中的hello()方法
public class Main {
public static void main(String[] args) {
// 1. 创建IOC容器,加载文件applicationContext.xml
// ApplicationContext 代表IOC容器,在初始化上下文时就实例化所有单例的Bean
// ClassPathXMLApplicationContext: 从类路
径下加载配置文件
// WebApplicationContext 继承了ApplicationContext接口,是ApplicationContext的扩展,是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2. 从IOC容器中获取Bean实例
// 利用id:helloWorld定位到IOC中bean
// getBean()方法两种获取实例方式
// 第一种:从IOC容器中获取Bean
HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");
// 第二种:利用类型返回IOC容器中的Bean,但要求IOC容器中必须只能有一个该类型的Bean
//HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
// 3. 调用HelloWorld类中的hello()方法
helloWorld.hello();
}
}
通过 setter 方法属性注入Bean
public class HelloWorld {
private String name;
}
public void setName(String name) {
this.name = name;
}
public void hello(){
System.out.println("Hello: " + name);
}
}
<bean id = "helloWorld" class="com.sangyu.test.bean.HelloWorld">
<property name="name" value="Spring"></property>
</bean>
<bean id = "helloWorld" class="com.sangyu.test.bean.HelloWorld">
<property name="name" >
<value>Spring</value> <!--value字节点-->
</property>
</bean>
通过构造方法注入 Bean
public class HelloWorld {
private String name;
private String city;
private int age;
public HelloWorld(String name,String city,int age){
this.name = name;
this.city = city;
this.age = age;
}
}
<!-- 通过构造方法来配置bean的属性 - 按照构造器参数的顺序-->
<bean id = "helloWorld" class="com.sangyu.test.bean.HelloWorld">
<constructor-arg value="Audi"/> <!-- 注意<construcotr-arg>中没有name属性-->
<constructor-arg value="shanghai"/>
<constructor-arg value="300000"/>
</bean>
<!-- 通过构造方法来配置bean的属性 - 按照index标记顺序-->
<bean id = "helloWorld" class="com.sangyu.test.bean.HelloWorld">
<constructor-arg index="0" value="sangyu"/>
<constructor-arg index="1" value="BJ"/>
<constructor-arg index="2" value="11"/>
</bean>
<!-- 通过构造方法来配置bean属性,按照参数列表类型 ,多个构造器并且参数不同,按照参数列表类型区分-->
<constructor-arg type="java.lang.String" value="sangyu"/>
<constructor-arg type="java.lang.String" value="BJ"/>
<constructor-arg type="int" value="1200"/>
spring 注入参数的类型介绍
在 Spring 的配置文件中,用户可以通过 Bean 的 property 元素进行参数注入。使用 property,不但可以将 String、int 等字面值注入到 Bean 中,还可以将集合、Map 等类型的注入到 Bean 中,此外还可以注入配置文件中其他定义的 Bean。
字面值
一般是指可用字符串表示的值,这些值可以通过<value>元素标签进行注入。
在默认情况下,基本数据类型及其封装类,String 等类型都可以采取字面值注入的方式:
<bean id="car2" class="com.sangyu.test.Car">
<constructor-arg index="0" type="java.lang.String" value="Audi02"/>
<!-- 如果字面值包含特殊字符可以使用<![CDATA[]]> 包裹起来-->
<constructor-arg index="1" type="java.lang.String">
<value><![CDATA[Shanghai^]]></value>
</constructor-arg>
<constructor-arg index="2" type="int">
<value>600000</value>
</constructor-arg>
</bean>
引用其他的 bean
- 在 bean 的配置文件中,通过
<ref>
元素或 ref 属性为 Bean 的属性或构造器参数指定对其他 bean 的引用
public class User {
private String name;
private String city;
private int age;
private Book book;
public Book getBook() {return book; }
public void setBook(Book book) {this.book = book;}
public int getAge() {return age;}
public String getCity() { return city;}
public String getName() {return name;}
public void setCity(String city) {this.city = city;}
public void setAge(int age) {this.age = age;}
public void setName(String name) {this.name = name;}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", city='" + city + '\'' +
", age=" + age +
", book=" + book +
'}';
}
}
public class Book {
private String bookName;
private int id;
private int price;
public int getId() { return id;}
public void setId(int id) { this.id = id;}
public void setBookName(String bookName) {this.bookName = bookName;}
public String getBookName() {return bookName;}
public void setPrice(int price) {this.price = price;}
public int getPrice() { return price;}
@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", id=" + id +
", price=" + price +
'}';
}
}
<bean id="book" class="com.sangyu.test.bean.Book">
<property name="bookName" value="HaHaHa"/>
<property name="id" value="1"/>
<property name="price" value="1200"/> <!-- 以分为单位,避免产生精度问题-->
</bean>
<bean id="user" class="com.sangyu.test.bean.User">
<property name="age" value="11"/>
<property name="city" value="BJ"/>
<property name="name" value="sangyu"/>
<property name="book" ref="book"/> <!-- 通过ref属性-->
</bean>
// 也通过<ref>元素
<bean id="user" class="com.sangyu.test.bean.User">
<property name="age" value="11"/>
<property name="city" value="BJ"/>
<property name="name" value="sangyu"/>
<property name="book">
<ref bean="book"></ref>
</property>
</bean>
public class Main {
public static void main(String[] args) {
ApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) ctx.getBean("user");
System.out.println(user);
}
}
- 也可以在属性或构造器里包含bean的声明,这样的 bean 称为内部 bean,但要注意的是:内部 bean 不能被外部引用,只能在内部使用,所以不需要声明 id
<bean id="user1" class="com.sangyu.test.bean.User">
<property name="name" value="sangyu01"/>
<property name="age" value="11"/>
<property name="city" value="BJ"/>
<property name="book">
<bean class="com.sangyu.test.bean.Book">
<property name="price" value="1200"/>
<property name="bookName" value="123"/>
<property name="id" value="2"/>
</bean>
</property>
</bean>
集合属性
Spring 中可以通过一组内置的 xml 标签(例如:<list>,<set>,<map> 来配置集合属性)
// 配置java.util.List类型的属性,需要指定<list>标签,
// 配置java.util.Set类型的属性,需要指定<set>标签,其他和<list>一样
// 通过<ref>指定对其他Bean的引用
<bean id="person" class="com.sangyu.test.Person">
<constructor-arg index="0" value="Mike"/>
<constructor-arg index="1" value="27"/>
<constructor-arg index="2">
<list>
<ref bean="car"></ref>
</list>
</constructor-arg>
</bean>
// 通过<value>指定简单的常量值
<bean id="person" class="com.sangyu.test.Person">
<constructor-arg index="0" value="Mike"/>
<constructor-arg index="1" value="27"/>
<constructor-arg index="2">
<list>
<value name="car"></ref>
</list>
</constructor-arg>
</bean>
// Java.util.Map通过 <map> 标签定义,<map> 使用多个<entry> 作为子标签,每个条目包含一个键和一个值
// 必须在<key>标签里定义键
<bean id="newPerson" class="com.sangyu.test.NewPerson">
<constructor-arg index="0" value="Rose"/>
<constructor-arg index="1" value="28"/>
<constructor-arg index="2">
<map>
<entry key="AA" value-ref="car"/>
</map>
</constructor-arg>
</bean>
properties
// 使用<props>定义java.util.Properties,该标签使用多个<prop>作为子标签,每个<prop>标签必须定义key属性
<bean id="dataSource" class="com.sangyu.test.DataSource">
<property name="properties">
<props>
<prop key="user">root</prop>
<prop key="password">1234</prop>
<prop key="jdbcUrl">jdbc:mysql:///test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
使用 utility scheme 定义集合
<!-- 配置单例的集合bean,以供多个bean进行引用,需要导入util命名空间-->
<util:list id="cars">
<ref bean="car"></ref>
<ref bean="car2"></ref>
</util:list>
<bean id="person4" class="com.sangyu.test.Person">
<constructor-arg index="0" value="Jack"/>
<constructor-arg index="1" value="29"/>
<constructor-arg index="2" ref="cars"/>
</bean>
使用 p 命名空间
<!-- 配置p命名空间为bean的属性赋值,需要先导入p命名空间-->
<!-- 这里需要注意的是,使用p空间要有无参构造器-->
<bean id="person5" class="com.sangyu.test.Person" p:age="30" p:name="Queen" p:car-ref="cars"></bean>
网友评论