Spring 通过 IOC 容器的方式管理 Bean。在本篇,将通过 xml 配置的方式介绍如何配置 Bean。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="animal" class="cn.cerish.entity.Animal">bean>
beans>
<aop:config>
<aop:aspect id="***" ref="***"/>
<aop:pointcut id="***" expression="****" />
aop:config>
xsi(xml schema instance):schemaLocation 提供了一个xml 命名空间到对应的XSD(Xml Schema Definition)文件的一个映射,它的值由一个或多个URI引用对组成,两个URI之间以空白符分隔(空格和换行均可)。c p 命名空间没有对应的 xsd 文件,是在 handler 中处理的。
xmlns:c xmlns:p 分别指定 c、p命名空间,用于简化示例 Bean 的配置,后面会讲。
还有比较冷门的配置(xml属于 xml 文件的知识,xsi 属于 xsd 文件的知识)
先定义几个类信息,作为 Bean 注入 ioc 容器
/* 省略 getter、setter 方法 */
public class Animal {
private Dog dog;
private Cat cat;
}
public class Dog {
private int age;
private String name;
}
public class Cat {
private int age;
private String name;
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="cat" name="cat1, cat2;cat5 cat6" class="cn.cerish.entity.Cat">bean>
<alias name="cat" alias="cat3">alias>
<alias name="cat1" alias="cat4">alias>
beans>
package cn.cerish;
import cn.cerish.entity.Cat;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IOCTest {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-animal.xml");
Cat cat = (Cat) ac.getBean("cat");
Cat cat1 = (Cat) ac.getBean("cat1");
Cat cat2 = (Cat) ac.getBean("cat2");
Cat cat3 = (Cat) ac.getBean("cat3");
Cat cat4 = (Cat) ac.getBean("cat4");
Cat cat5 = (Cat) ac.getBean("cat5");
Cat cat6 = (Cat) ac.getBean("cat6");
System.out.println("cat: " + cat);
System.out.println("cat1: " + cat1);
System.out.println("cat2: " + cat2);
System.out.println("cat3: " + cat3);
System.out.println("cat4: " + cat4);
System.out.println("cat5: " + cat5);
System.out.println("cat6: " + cat6);
}
}
<import resource="spring-dog.xml">import>
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="dog" class="cn.cerish.entity.Dog">bean>
beans>
package cn.cerish;
import cn.cerish.entity.*;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IOCTest {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-cat.xml");
Cat cat = (Cat) ac.getBean("cat");
System.out.println("cat: " + cat);
Dog dog = (Dog) ac.getBean("dog");
System.out.println("dog: " + dog);
}
}
<description>用来配置 Animal 信息的文件description>
new ClassPathXmlApplicationContext("spring-animal.xml").getBean("XXX");
得到的 Bean 实例,默认经过空构造生成,属性值为默认的。如下图所示package cn.cerish.entity;
import java.util.*;
public class Student {
private int age;
private String name;
private Cat cat;
private String[] books;
private List<String> hobbys;
private Map<String, String> card;
private Set<String> games;
private String wife;
private Properties info;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public List<String> getHobbys() {
return hobbys;
}
public void setHobbys(List<String> hobbys) {
this.hobbys = hobbys;
}
public Map<String, String> getCard() {
return card;
}
public void setCard(Map<String, String> card) {
this.card = card;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public String getWife() {
return wife;
}
public void setWife(String wife) {
this.wife = wife;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
", cat=" + cat +
", books=" + Arrays.toString(books) +
", hobbys=" + hobbys +
", card=" + card +
", games=" + games +
", wife='" + wife + '\'' +
", info=" + info +
'}';
}
}
<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
https://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<description>本配置文件用于展示 property 的属性配置description>
<bean id="student" class="cn.cerish.entity.Student">
<property name="age" value="18">property>
<property name="name" value="cerish">property>
<property name="cat" ref="cat" />
<property name="books">
<list>
<value>红楼梦value>
<value>西游记value>
<value>三国演义value>
<value>水浒传value>
list>
property>
<property name="hobbys">
<list>
<value>听歌value>
<value>敲代码value>
list>
property>
<property name="card">
<map>
<entry key="idCard" value="4454644546">entry>
map>
property>
<property name="games">
<set>
<value>Lolvalue>
<value>王者荣耀value>
set>
property>
<property name="info">
<props>
<prop key="学号">1520711prop>
<prop key="性别">男prop>
props>
property>
<property name="wife">
<null>null>
property>
bean>
<bean id="cat" class="cn.cerish.entity.Cat">
<property name="age" value="2" />
<property name="name" value="miao~" />
bean>
beans>
public class IOCTest {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-student.xml");
Student student = (Student) ac.getBean("student");
System.out.println("student: " + student);
}
}
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="dogC" class="cn.cerish.entity.Dog" c:age="3" c:name="wangC">bean>
<bean id="dogP" class="cn.cerish.entity.Dog" p:age="2" p:name="wangP~">bean>
beans>
public class IOCTest {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-dog.xml");
Dog dogC = (Dog) ac.getBean("dogC");
Dog dogP = (Dog) ac.getBean("dogP");
System.out.println("dogC: " + dogC);
System.out.println("dogP: " + dogP);
}
}
自动装配功能,从前面可以看到,若 Bean 对象的个数较多或者属性较多,那么需要配置很多个 property,spring 提供了 autowire 属性帮我们做了这件事。
autowire 的取值有五个
spring-dog.xml 配置如下,独自运行查看结果(例如,name 正确,类型不正确?类型多个?)
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="animalType" class="cn.cerish.entity.Animal" autowire="byType">bean>
<bean id="catType" class="cn.cerish.entity.Cat">
<property name="age" value="2">property>
<property name="name" value="miaoType~">property>
bean>
<bean id="dogType" class="cn.cerish.entity.Dog">
<property name="age" value="2">property>
<property name="name" value="wangType~">property>
bean>
beans>
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="animalType" class="cn.cerish.entity.Animal" autowire="byType">bean>
<bean id="catType" class="cn.cerish.entity.Cat">
<property name="age" value="2">property>
<property name="name" value="miao~">property>
bean>
<bean id="dogType" class="cn.cerish.entity.Dog" autowire-candidate="false">
<property name="age" value="2">property>
<property name="name" value="wang~">property>
bean>
beans>
public class IOCTest {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-animal.xml");
Animal animal = (Animal) ac.getBean("animalType");
System.out.println("animal: " + animal);
}
}
设置 Bean 的作用域
实体类
public class Person {
private int age;
private String name;
....省略 getter、setter
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="personSingleton" class="cn.cerish.entity.Person" scope="singleton">bean>
<bean id="personPrototype" class="cn.cerish.entity.Person" scope="prototype">bean>
beans>
public class IOCTest {
@Test
public void test() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-person.xml");
Person person1 = (Person) ac.getBean("personSingleton");
Person person2 = (Person) ac.getBean("personSingleton");
Person person3 = (Person) ac.getBean("personSingleton");
System.out.println("person1: " + person1);
System.out.println("person2: " + person2);
System.out.println("person3: " + person3);
System.out.println("==============================");
Person person4 = (Person) ac.getBean("personPrototype");
Person person5 = (Person) ac.getBean("personPrototype");
Person person6 = (Person) ac.getBean("personPrototype");
System.out.println("person4: " + person4);
System.out.println("person5: " + person5);
System.out.println("person6: " + person6);
}
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="animal" class="cn.cerish.entity.Animal" autowire="byType">bean>
<bean id="cat" class="cn.cerish.entity.Cat">
<property name="age" value="2">property>
<property name="name" value="miao~">property>
bean>
<bean id="dog1" class="cn.cerish.entity.Dog" primary="true">
<property name="age" value="2">property>
<property name="name" value="wang~">property>
bean>
<bean id="dog2" class="cn.cerish.entity.Dog">
<property name="age" value="3">property>
<property name="name" value="wang~">property>
bean>
<bean id="dog3" class="cn.cerish.entity.Dog">
<property name="age" value="4">property>
<property name="name" value="wang~">property>
bean>
beans>
@Test
public void testPrimary() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-animal.xml");
Animal animal = (Animal) ac.getBean("animal");
System.out.println("animal" + animal);
}
/* Person 类 */
public class Person {
private int age;
private String name;
public Person() {
System.out.println("我是 person 空构造");
}
}
/* Animal 类 */
public class Animal {
private int age;
private String name;
public Animal () {
System.out.println("我是 Animal 空构造");
}
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="personSingleton" class="cn.cerish.entity.Person" scope="singleton" lazy-init="true">bean>
<bean id="animalSingleton" class="cn.cerish.entity.Animal" scope="singleton">bean>
beans>
@Test
public void testLazyInit() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-person.xml");
}
public class Person {
private int age;
private String name;
public Person() {
System.out.println("我是 person 空构造");
}
public void initMethod() {
System.out.println("我是 Person 类的 initMethod");
}
public void destoryMethod() {
System.out.println("我是 Person 类的 destoryMethod");
}
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="personInitDestory" class="cn.cerish.entity.Person" init-method="initMethod" destroy-method="destoryMethod">bean>
beans>
@Test
public void testInitDestory() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-person.xml");
Person person = (Person) ac.getBean("personInitDestory");
/* 关闭容器,意在销毁 Bean */
((ClassPathXmlApplicationContext) ac).close();
}
/* Car:实体类 */
public class Car {}
/* CarFactory: 生产 Car 的工厂类 */
public class CarFactory {
public static Car getCar() {
System.out.println("我是 static 方法创建的 Car");
return new Car();
}
public Car getInstanceCar() {
System.out.println("我是 static 方法创建的 Car");
return new Car();
}
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="staticCar" class="cn.cerish.entity.CarFactory" factory-method="getCar" lazy-init="true">bean>
<bean id="carFactory" class="cn.cerish.entity.CarFactory" />
<bean id="instanceCar" factory-bean="carFactory" factory-method="getInstanceCar" lazy-init="true">bean>
beans>
@Test
public void testFactoryBean() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-car.xml");
// 静态方法获取对象
Car staticCar = (Car) ac.getBean("staticCar");
System.out.println("======================");
// 非静态方法获取对象
Car instanceCar = (Car) ac.getBean("instanceCar");
}
public class Teacher {
private String school;
private String name;
private int age;
....getter setter 方法
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="major" class="cn.cerish.entity.Major">
<property name="majorName" value="计算机技术">property>
bean>
<bean name="schoolName" abstract="true">
<property name="school" value="清华大学">property>
bean>
<bean id="teacher1" parent="major" class="cn.cerish.entity.Teacher">
<property name="name" value="teacher1">property>
<property name="age" value="28">property>
<property name="school" value="北京大学">property>
bean>
<bean id="teacher2" parent="major" class="cn.cerish.entity.Teacher">
<property name="name" value="teacher2">property>
<property name="age" value="38">property>
<property name="school" value="北京大学">property>
bean>
<bean id="teacher3" parent="schoolName" class="cn.cerish.entity.Teacher">
<property name="name" value="teacher3">property>
<property name="age" value="48">property>
<property name="majorName" value="计算机技术">property>
bean>
<bean id="teacher4" parent="schoolName" class="cn.cerish.entity.Teacher">
<property name="name" value="teacher4">property>
<property name="age" value="58">property>
<property name="majorName" value="计算机技术">property>
bean>
beans>
@Test
public void testAbstract() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-teacher.xml");
Teacher teacher1 = (Teacher) ac.getBean("teacher1");
System.out.println("teacher1: " + teacher1);
Teacher teacher2 = (Teacher) ac.getBean("teacher2");
System.out.println("teacher2: " + teacher2);
Teacher teacher3 = (Teacher) ac.getBean("teacher3");
System.out.println("teacher3: " + teacher3);
Teacher teacher4 = (Teacher) ac.getBean("teacher4");
System.out.println("teacher4: " + teacher4);
}
public class Teacher {
private String school;
private String name;
private int age;
}
public class Major {
private String majorName;
}
<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
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="teacher" class="cn.cerish.entity.Teacher" init-method="initMethod" destroy-method="destoryMethod" depends-on="major">
<property name="name" value="teacher">property>
<property name="age" value="28">property>
bean>
<bean id="major" class="cn.cerish.entity.Major" init-method="initMethod" destroy-method="destoryMethod">
<property name="majorName" value="计算机科学">property>
bean>
beans>
@Test
public void testDependOn() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-major.xml");
((ClassPathXmlApplicationContext) ac).close();
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="dog" class="cn.cerish.entity.Dog">
<property name="name" value="wang~~">property>
<property name="age" value="2">property>
bean>
<bean id="dog" class="cn.cerish.entity.Cat">
<property name="name" value="miao~~">property>
<property name="age" value="1">property>
bean>
beans>
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'dog' is already used in this <beans> element
Offending resource: class path resource [spring-dog.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:72)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:119)...
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="dog" class="cn.cerish.entity.Dog" p:name="wangP:~" p:age="1">
<property name="name" value="wangProperty~">property>
<property name="age" value="2">property>
bean>
beans>
@Test
public void testPriority() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-dog.xml");
Dog dog = (Dog) ac.getBean("dog");
System.out.println(dog);
}
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Property 'age' is already defined using both <property> and inline syntax. Only one approach may be used per property.
Offending resource: class path resource [spring-dog.xml]
at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:72)
at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:119)...