一、名词解释:
IoC(Inversion of Control):控制反转
DI(Dependency Injection):依赖注入
我们常说的依赖注入和控制反转在spring中是同等概念,控制反转是由依赖注入实现的。所谓依赖注入是指容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。
二、依赖注入法方法:
Spring IoC容器负责创建bean,并通过容器将功能类Bean注入到你需要的Bean中。spring提供的依赖注入方式有:(1)xml文件配置、(2)注解、(3)Java配置、(4)groovy配置(不是主要常用的,不做了解)
无论是xml配置、注解、还是Java配置都被称为配置元数据,所谓元数据,即描述数据的数据。元数据本身不剧本任何可执行的能力,只能通过外界代码对这一些元数据解析后进行一些有意义的操作。接下来我们就分别看下各种注入方式。
1、xml配置文件的方式:
xml配置文件的方式又分为:(1)setter注入(2)构造方法注入。
(1)sertter注入又叫属性注入:
setter方法注入顾名思义,对应的类中一定要有对应属性的sertter方法。
(2)构造方法注入顾名思义,对应类中一定要有对应格式的构造方法。
具体配置看下面代码:
applicationContext.xml配置文件代码如下:
<?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:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd"> <!-- 配置bean class:bean的全类名,通过反射的方式在IOC容器中创建bean id:表示容器中的bean,id唯一 --> <!-- 通过setter注入,配置bean的属性 --> <bean id="helloWorld" class="me.spring.beans.HelloWorld"> <property name="name" value="Spring"></property> </bean> <!-- 通过构造方法,配置bean的属性 --> <bean id="car" class="me.spring.beans.Car"> <constructor-arg value="Audi" index="0"></constructor-arg> <constructor-arg value="ShangHai" index="1"></constructor-arg> <constructor-arg value="300000" index="2"></constructor-arg> </bean> <!-- 使用构造器注入的属性值可以指定参数的类型,参数的位置,以区分重载的构造器 如果字面值包括特殊字符,可以使用<![CDATA[]]>包裹起来 属性值也可以使用value子节点进行配置 --> <bean id="car2" class="me.spring.beans.Car"> <constructor-arg value="BaoMa"></constructor-arg> <constructor-arg type="java.lang.String"> <value><![CDATA[<BeiJing>]]></value> </constructor-arg> <constructor-arg value="240" type="int"></constructor-arg> </bean> <!-- 可以使用property标签的ref属性建立bean之间的引用关系 --> <bean id="person" class="me.spring.beans.Person"> <property name="name" value="Tom"></property> <property name="age" value="24"></property> <!-- <property name="car" ref="car"></property> --> <property name="car"> <ref bean="car2"/> </property> <!-- <property name="car"> <bean class="me.spring.beans.Car"> <constructor-arg value="Ford"></constructor-arg> <constructor-arg value="ChangAn"></constructor-arg> <constructor-arg value="2354395"></constructor-arg> </bean> </property> --> </bean> <bean id="person2" class="me.spring.beans.Person"> <constructor-arg value="Jerry"></constructor-arg> <constructor-arg value="25"></constructor-arg> <constructor-arg ref="car2"></constructor-arg> <!-- 为级联属性赋值 注意:属性需要初始化后才能为级联属性赋值,与Struct2不同 这里必须依据Person的getter和setter方法,不能为car2的 --> <property name="car.price" value="454600"></property> </bean> <!-- 测试如何配置集合属性 --> <bean id="person3" class="me.spring.beans.colltions.Person"> <property name="name" value="Mike"></property> <property name="age" value="30"></property> <property name="cars"> <!-- 使用list节点为属性为list类型的成员变量赋值 --> <list> <ref bean="car"/> <ref bean="car2"/> <bean class="me.spring.beans.Car"> <constructor-arg value="Ford"></constructor-arg> <constructor-arg value="ChangAn"></constructor-arg> <constructor-arg value="2354395" type="double"></constructor-arg> </bean> </list> </property> </bean> <bean id="newPerson" class="me.spring.beans.colltions.NewPerson"> <property name="name" value="Rose"></property> <property name="age" value="23"></property> <property name="cars"> <!-- 使用map节点以及map的子节点entry节点,配置类型为map的成员变量 --> <map> <entry key="AA" value-ref="car"></entry> <entry key="BB" value-ref="car2"></entry> </map> </property> </bean> <!-- 配置properties属性值 --> <bean id="dataSource" class="me.spring.beans.colltions.DataSource"> <property name="properties"> <!-- 使用props节点和其子节点prop为properties属性赋值 --> <props > <prop key="user">root</prop> <prop key="password">root</prop> <prop key="jdbcUrl">jdbc:mysql://localhost:3306/sm</prop> <prop key="driverClass">com.mysql.jdbc.Driver</prop> </props> </property> </bean> <!-- 配置单例的集合bean,以便多个bean进行引用,需要导入util命名空间 --> <util:list id="cars"> <ref bean="car"/> <ref bean="car2"/> </util:list> <bean id="person4" class="me.spring.beans.colltions.Person"> <property name="name" value="Jack"></property> <property name="age" value="34"></property> <property name="cars" ref="cars"></property> </bean> <!-- 通过p命名空间为bean的属性赋值,需要导入p命名空间,相对于传统的配置较为简洁 --> <bean id="person5" class="me.spring.beans.colltions.Person" p:name="Queen" p:age="32" p:cars-ref="cars"></bean> </beans>
相关的实体类代码如下:
Person.java
package me.spring.beans; 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; } public Person(){}; public Person(String name, int age, Car car){ super(); this.name = name; this.age = age; this.car = car; } @Override public String toString() { // TODO Auto-generated method stub return "Person [name= " + name + ", age=" + age + ", car=" + car + "]"; } }
Car.java
package me.spring.beans; public class Car { private String brand; private String corp; private double price; private int maxSpeed; public Car(String brand, String corp, double price){ super(); this.brand = brand; this.corp = corp; this.price = price; } public Car(String brand, String corp, int maxSpeed){ super(); this.brand = brand; this.corp = corp; this.maxSpeed = maxSpeed; } public void setPrice(double price){ this.price = price; } public double getPrice(){ return price; } @Override public String toString() { // TODO Auto-generated method stub return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxSpeed=" + maxSpeed + "]"; } }
HelloWorld.java
package me.spring.beans; public class HelloWorld { private String name; public void setName(String name){ this.name = name; } public void hello(){ System.out.println("hello" + name); } }
Main.java
package me.spring.beans; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args){ //1.创建Spring的IOC容器 //ApplicationContext代表IOC容器 //ClassPathApplicationContext是ApplicationContext的实现类,该实现从类路径下加载配置文件 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.从IOC容器中获取bean实例 //利用id定位到IOC容器中的bean HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld"); //2.1 利用类型返回IOC容器中的bean,但要求IOC容器中只能有一个该类型的bean // HelloWorld helloWorld1 = ctx.getBean(HelloWorld.class); //3.调用hello方法 helloWorld.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("person"); System.out.println(person); Person person2 = (Person) ctx.getBean("person2"); System.out.println(person2); } }
有关Map和List集合有关的注入方式,代码如下:(与上面介绍类不在同一包下)
Person.java
package me.spring.beans.colltions; import java.util.List; import me.spring.beans.Car; public class Person { private String name; private int age; private List<Car> cars; 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 List<Car> getCars() { return cars; } public void setCars(List<Car> cars) { this.cars = cars; } public Person(){} public Person(String name, int age, List<Car> cars){ super(); this.name = name; this.age = age; this.cars = cars; } @Override public String toString() { // TODO Auto-generated method stub return "Person [name=" + name + ", age=" + age + ", cars=" + cars + "]"; } }
NewPerson.java
package me.spring.beans.colltions; import java.util.Map; import me.spring.beans.Car; public class NewPerson { private String name; private int age; private Map<String, Car> cars; 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 Map<String, Car> getCars() { return cars; } public void setCars(Map<String, Car> cars) { this.cars = cars; } public NewPerson() {} public NewPerson(String name, int age, Map<String, Car> cars){ super(); this.name = name; this.age = age; this.cars = cars; } @Override public String toString() { // TODO Auto-generated method stub return "NewPerson [name=" + name + ", age=" + age + ", cars=" + cars + "]"; } }
DataSource.java
package me.spring.beans.colltions; 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 "DataSource [properties=" + properties + "]"; } }
Main.java
package me.spring.beans.colltions; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args){ ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); Person person = (Person) ctx.getBean("person5"); System.out.println(person); NewPerson newPerson = (NewPerson) ctx.getBean("newPerson"); System.out.println(newPerson); DataSource dataSource = (DataSource) ctx.getBean("dataSource"); System.out.println(dataSource); } }