首页 > 代码库 > Spring入门第三课
Spring入门第三课
属性注入
属性注入就是通过setter方法注入Bean的属性值或依赖的对象。
属性植入使用<property>元素,使用name属性指定Bean的属性名称,value属性或者<value>子节点指定属性值
属性注入是实际应用中最常用的注入方式。
构造方法注入
通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例化以后就可以使用。
构造器注入在<constructor-arg>元素里申明属性,<constructor-arg>中没有name属性
package logan.spring.study; public class Car { private String brand; private String corp; private int price; private int maxspeed; public Car(String brand, String corp, int price) { super(); this.brand = brand; this.corp = corp; this.price = price; } @Override public String toString() { return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxspeed=" + maxspeed + "]"; } }
package logan.spring.study; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub //1.创建Spring的IOC容器对象 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.从 IOC容器中获取Bean实例 HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello"); //HelloWorld hello = ctx.getBean(HelloWorld.class); //3.调用hello方法 //System.out.println(hello); Car car = ctx.getBean(Car.class); System.out.println(car); } }
<?xml version="1.0" encoding="UTF-8"?> <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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="Audi"></constructor-arg> <constructor-arg value="Shanghai"></constructor-arg> <constructor-arg value="3000000"></constructor-arg> </bean> </beans>
还可以这样配置
<?xml version="1.0" encoding="UTF-8"?> <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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="Audi" index="0"></constructor-arg> <constructor-arg value="Shanghai" index="1"></constructor-arg> <constructor-arg value="3000000" index="2"></constructor-arg> </bean> </beans>
当如下配置时,会不合逻辑
<?xml version="1.0" encoding="UTF-8"?> <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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="Audi" index="0"></constructor-arg> <constructor-arg value="Shanghai" index="1"></constructor-arg> <constructor-arg value="3000000" index="2"></constructor-arg> </bean> <bean id="car2" class="logan.spring.study.Car"> <constructor-arg value="Baoma"></constructor-arg> <constructor-arg value="Shanghai"></constructor-arg> <constructor-arg value="240"></constructor-arg> </bean> </beans>
package logan.spring.study; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub //1.创建Spring的IOC容器对象 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.从 IOC容器中获取Bean实例 HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello"); //HelloWorld hello = ctx.getBean(HelloWorld.class); //3.调用hello方法 //System.out.println(hello); Car car = (Car) ctx.getBean("car"); System.out.println(car); Car car2 = (Car) ctx.getBean("car2"); System.out.println(car2); } }
这个是得到的结果
五月 18, 2017 10:00:14 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Thu May 18 22:00:14 CST 2017]; root of context hierarchy 五月 18, 2017 10:00:14 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] HelloWorld‘s Constructor... HelloWorld‘s Constructor... Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0] Car [brand=Baoma, corp=Shanghai, price=240.0, maxspeed=0]
可以看到240没有赋值到maxSpeed上。
如下修改配置文件可以正确赋值
<?xml version="1.0" encoding="UTF-8"?> <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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Audi" index="0"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Shanghai" index="1"></constructor-arg> <constructor-arg value="http://www.mamicode.com/3000000" index="2" type="double"></constructor-arg> </bean> <bean id="car2" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Baoma" type="java.lang.String"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Shanghai" type="java.lang.String"></constructor-arg> <constructor-arg value="http://www.mamicode.com/240" type="int"></constructor-arg> </bean> </beans>
得到如下结果:使用构造器注入属性值时可以指定参数的位置和参数的类型!以区分重载的构造器
五月 18, 2017 10:04:26 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Thu May 18 22:04:26 CST 2017]; root of context hierarchy 五月 18, 2017 10:04:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] HelloWorld‘s Constructor... HelloWorld‘s Constructor... Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0] Car [brand=Baoma, corp=Shanghai, price=0.0, maxspeed=240]
还可以如下配置,使用子节点给属性赋值
<?xml version="1.0" encoding="UTF-8"?> <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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Audi" index="0"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Shanghai" index="1"></constructor-arg> <constructor-arg value="http://www.mamicode.com/3000000" index="2" type="double"></constructor-arg> </bean> <bean id="car2" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Baoma" type="java.lang.String"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Shanghai" type="java.lang.String"></constructor-arg> <constructor-arg type="int"> <value>250</value> </constructor-arg> </bean> </beans>
字面值:可以使用字符串表示的值,可以通过<value>元素标签或者value属性进行注入。
基本数据类型及其封装类,String等类型都可以采取字面值注入的方式
若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来。
<?xml version="1.0" encoding="UTF-8"?> <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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Audi" index="0"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Shanghai" index="1"></constructor-arg> <constructor-arg value="http://www.mamicode.com/3000000" index="2" type="double"></constructor-arg> </bean> <bean id="car2" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Baoma" type="java.lang.String"></constructor-arg> <constructor-arg type="java.lang.String"> <value><![CDATA[<Shanghai>]]></value> </constructor-arg> <constructor-arg type="int"> <value>250</value> </constructor-arg> </bean> </beans>
下面看Bean相互引用
组成应用程序的Bean经常需要相互协作以完成应用程序的功能。要使Bean能够相互访问,就必须在Bean配置文件中指定对Bean的引用。
在Bean的配置文件中,可以通过<ref>元素或者ref属性为Bean的属性或者构造器参数指定对Bean的引用。
也可以在属性或者构造器里包含Bean的声明,这样的Bean称为内部Bean。
package logan.spring.study; public class Person { private String name; private int age; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", car=" + car + "]"; } }
<?xml version="1.0" encoding="UTF-8"?> <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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="Audi" index="0"></constructor-arg> <constructor-arg value="Shanghai" index="1"></constructor-arg> <constructor-arg value="3000000" index="2" type="double"></constructor-arg> </bean> <bean id="car2" class="logan.spring.study.Car"> <constructor-arg value="Baoma" type="java.lang.String"></constructor-arg> <constructor-arg type="java.lang.String"> <value><![CDATA[<Shanghai>]]></value> </constructor-arg> <constructor-arg type="int"> <value>250</value> </constructor-arg> </bean> <bean id="person" class="logan.spring.study.Person"> <property name="name" value="Tom"></property> <property name="age" value="24"></property> <property name="car" ref="car2"></property> </bean> </beans>
package logan.spring.study; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub //1.创建Spring的IOC容器对象 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.从 IOC容器中获取Bean实例 HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello"); //HelloWorld hello = ctx.getBean(HelloWorld.class); //3.调用hello方法 //System.out.println(hello); Car car = (Car) ctx.getBean("car"); System.out.println(car); Car car2 = (Car) ctx.getBean("car2"); System.out.println(car2); Person person = ctx.getBean(Person.class); System.out.println(person); } }
下面是输出结果
五月 18, 2017 10:21:47 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Thu May 18 22:21:47 CST 2017]; root of context hierarchy 五月 18, 2017 10:21:47 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] HelloWorld‘s Constructor... HelloWorld‘s Constructor... Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0] Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250] Person [name=Tom, age=24, car=Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250]]
看内部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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Audi" index="0"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Shanghai" index="1"></constructor-arg> <constructor-arg value="http://www.mamicode.com/3000000" index="2" type="double"></constructor-arg> </bean> <bean id="car2" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Baoma" type="java.lang.String"></constructor-arg> <constructor-arg type="java.lang.String"> <value><![CDATA[<Shanghai>]]></value> </constructor-arg> <constructor-arg type="int"> <value>250</value> </constructor-arg> </bean> <bean id="person" class="logan.spring.study.Person"> <property name="name" value="http://www.mamicode.com/Tom"></property> <property name="age" value="http://www.mamicode.com/24"></property> <property name="car"> <bean class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Ford"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Changan"></constructor-arg> <constructor-arg value="http://www.mamicode.com/20000000" type="double"></constructor-arg> </bean> </property> </bean> </beans>
运行结果
五月 18, 2017 10:36:26 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Thu May 18 22:36:26 CST 2017]; root of context hierarchy 五月 18, 2017 10:36:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] HelloWorld‘s Constructor... HelloWorld‘s Constructor... Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0] Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250] Person [name=Tom, age=24, car=Car [brand=Ford, corp=Changan, price=2.0E7, maxspeed=0]]
注意:内部Bean不能被外部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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数 id:表示容器的bean,id唯一 --> <bean id="hello" class="logan.spring.study.HelloWorld"> </bean> <bean id="hello2" class="logan.spring.study.HelloWorld"> </bean> <!-- 通过构造方法来配置Bean的属性 --> <bean id="car" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Audi" index="0"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Shanghai" index="1"></constructor-arg> <constructor-arg value="http://www.mamicode.com/3000000" index="2" type="double"></constructor-arg> </bean> <bean id="car2" class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Baoma" type="java.lang.String"></constructor-arg> <constructor-arg type="java.lang.String"> <value><![CDATA[<Shanghai>]]></value> </constructor-arg> <constructor-arg type="int"> <value>250</value> </constructor-arg> </bean> <bean id="person" class="logan.spring.study.Person"> <property name="name" value="http://www.mamicode.com/Tom"></property> <property name="age" value="http://www.mamicode.com/24"></property> <property name="car"> <bean class="logan.spring.study.Car"> <constructor-arg value="http://www.mamicode.com/Ford"></constructor-arg> <constructor-arg value="http://www.mamicode.com/Changan"></constructor-arg> <constructor-arg value="http://www.mamicode.com/20000000" type="double"></constructor-arg> </bean> </property> </bean> <bean id="person2" class="logan.spring.study.Person"> <constructor-arg value="http://www.mamicode.com/Jerry"></constructor-arg> <constructor-arg value="http://www.mamicode.com/25"></constructor-arg> <constructor-arg ref="car"></constructor-arg> </bean> </beans>
package logan.spring.study; public class Person { private String name; private int age; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", car=" + car + "]"; } public Person() { // TODO Auto-generated constructor stub } public Person(String name, int age, Car car) { super(); this.name = name; this.age = age; this.car = car; } }
package logan.spring.study; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub //1.创建Spring的IOC容器对象 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.从 IOC容器中获取Bean实例 HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello"); //HelloWorld hello = ctx.getBean(HelloWorld.class); //3.调用hello方法 //System.out.println(hello); Car car = (Car) ctx.getBean("car"); System.out.println(car); Car car2 = (Car) ctx.getBean("car2"); System.out.println(car2); Person person = (Person) ctx.getBean("person2"); System.out.println(person); } }
输出结果如下:
五月 18, 2017 10:43:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Thu May 18 22:43:51 CST 2017]; root of context hierarchy 五月 18, 2017 10:43:51 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [applicationContext.xml] HelloWorld‘s Constructor... HelloWorld‘s Constructor... Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0] Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250] Person [name=Jerry, age=25, car=Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0]]
Spring入门第三课