Spring的依赖注入

创建对象给属性赋值

DI的分类

1. set注入:spring调用类的set方法,在set方法可以实现属性的赋值

2. 构造注入:spring调用类的有参构造方法,创建对象,在构造方法中完成赋值

基于XML的依赖注入

1、set注入(设置注入)

spring调用set方法,完成属性赋值

1)简单类型的set注入

     语法

 <bean id="xx" class="yy">  
   <propery name="属性名1" value="属性性值"/>
   <propery name="属性名2" value="属性值" />
	...
</bean>

实体类

public class student {
	private String name;
	private int age;

	public String getName() {
	     return name;
	}

	public void setName(String name) {
	    System.out.println("setName"+name);
	    this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		System.out.println("setAge"+age);
		this.age = age;
	}

	@Override
	public String toString() {
	return "student{" +
	"name='" + name + '\'' +
	", age=" + age +
	'}';
	}
}

beans

<bean id="student" class="cn.com.Ycy.spring.Beans.student">
	<property name="name" value="张三"/>
	<property name="age" value="21"/>
</bean>

测试类:

@Test
public void test5(){
  String config = "bean01/applicationContext.xml";
	ApplicationContext ac= new ClassPathXmlApplicationContext(config);
	Object student = ac.getBean("student");
	System.out.println(student);
}

总结

1.就是<property name="name" value="张三"/>这个就是调用setName("张三");方法
2.并且实体类中必须有set方法,不然会报错:
	Bean property 'age' is not writable or has an invalid setter method.
3. 如果没有属性比如id,但是xml文件写了,并且实体类中有setId()这个方法,是可以运行的
	<property name="id" value="001"/>
	原因:<property name="xx" value="001"/>就是调用实体类中的setXx()方法
4.所以由3可知,可以给非自定义类设置值,只要它的里面有setXx()方法就可以
2)引用类型的set注入

     语法

 <bean id="xx" class="yy">
	<propery name="属性名1" value="属性性值"/>
	<propery name="属性名2" value="属性值" />
	<!--引用类型-->
	<propery name="属性名3" ref="bean的id值"/>
	...
</bean>

代码演示

实体类
public class student {
	private String name;
	private int age;
	private school schools;

	public school getSchools() {
		return schools;
	}
	public void setSchools(school schools) {
	 this.schools = schools;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		System.out.println("setName"+name);
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		System.out.println("setAge"+age);
		this.age = age;
	}
	@Override
	public String toString() {
		return "student{" +
		"name='" + name + '\'' +
		", age=" + age +
		", schools=" + schools +
		'}';
	}
}
beans中:
<bean id="student" class="cn.com.Ycy.spring.Beans.student">
	<property name="name" value="张三"/>
	<property name="age" value="21"/>
	<property name="schools" ref="schools"/>
</bean>
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
	<property name="name" value="北京大学"/>
	<property name="address" value="北京"/>
	<property name="id" value="0052"/>
</bean>
测试类
@Test
public void test5(){
String config = "bean01/applicationContext.xml";
	ApplicationContext ac= new ClassPathXmlApplicationContext(config);
	Object student = ac.getBean("student");
	System.out.println(student);
}

2、构造注入

spring调用类有参构造方法,在创建对象的同时,在构造方法中给属性赋值
构造注入使用 :< constructor-arg >标签

语法详解
< constructor-arg >标签:
一个表示构造方法的一个参数
< constructor-arg>标签属性:
name: 表示构造方法的形参名
index:表示构造方法的参数位置,参数从左往右的顺序是 0、1、2…
value:构造方法的形参类型是简单类型,使用value
ref:构造方法的形参类型是引用类型,使用ref,就是引入在ioc容器中存在的对象
使用name属性构造方法注入
代码
实体类
public class student {
    private String name;
    private int age;
    private school schools;


    public student() {
        System.out.println("无参构造方法");
    }
    public student(String name, int age, school schools) {
        this.name = name;
        this.age = age;
        this.schools = schools;
    }

    public school getSchools() {
        return schools;
    }

    public void setSchools(school schools) {
        this.schools = schools;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("setName"+name);
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("setAge"+age);
        this.age = age;
    }

    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", schools=" + schools +
                '}';
    }
}
//school类
public class school {
    private String name;
    private String address;
    private int id;

    public void setName(String name) {
        this.name = name;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "school{" +
             "name='" + name + '\'' +
              ", address='" + address + '\'' +
            ", id=" + id +
           '}';
    }
}

bean.xml
   <bean id="student" class="cn.com.Ycy.spring.Beans.student">
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="20"/>
        <constructor-arg name="schools" ref="schools"/>
    </bean>
    <bean id="schools" class="cn.com.Ycy.spring.Beans.school">

        <property name="name" value="北京大学"/>
        <property name="address" value="北京"/>
        <property name="id" value="0052"/>
    </bean>
测试类
@Test
public void test06(){
	String config = "bean01/applicationContext.xml";
	ApplicationContext ac= new ClassPathXmlApplicationContext(config);
	Object student = ac.getBean("student");
	System.out.println(student);
}
使用index属性构造方法注入,就是beans.xml不同
<bean name="mystudent" class="cn.com.Ycy.spring.Beans.student">
	<constructor-arg index="0" value="李四"/>
	<constructor-arg index="1" value="21"/>
	<constructor-arg index="2" ref="schools"/>
</bean>
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">	
	<property name="name" value="北京大学"/>
	<property name="address" value="北京"/>
	<property name="id" value="0052"/>
</bean>

省略index也是可以的

<bean name="mystudent" class="cn.com.Ycy.spring.Beans.student">
	<constructor-arg  value="李四"/>
	<constructor-arg  value="21"/>
	<constructor-arg  ref="schools"/>
</bean>
<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
	<property name="name" value="北京大学"/>
	<property name="address" value="北京"/>
	<property name="id" value="0052"/>
</bean>
在这也是可以使用构造注入,创建非自定义的类,如File,Date…

引用类型的自动注入

Spring框架根据数据某些规则给引用类型赋值,不用我们在给引用类型赋值

分类:

1. byName
2. byType
1、byName:(按照名称注入): Java类中引用类型的属性名和Spring容器中的配置文件的id名称一样,且数据类型是一致的,这样容器中的bean,Spring会自动给引用类型赋值。

语法:

<bean id="xx" class="yy" autowire="byName">
		简单数据类型属性赋值
</bean>

beans.xml文件

<bean id="schools" class="cn.com.Ycy.spring.Beans.school">
	<property name="name" value="北京大学"/>
	<property name="address" value="北京"/>
	<property name="id" value="0052"/>
</bean>
 <bean id="student2" class="cn.com.Ycy.spring.Beans.student" autowire="byName">
	<property name="name" value="王二"/>
	<property name="age" value="21"/>
</bean>
测试类
	@Test
    public void test08(){
        String config = "bean01/applicationContext.xml";
        ApplicationContext ac= new ClassPathXmlApplicationContext(config);
        Object student = ac.getBean("student2");
        System.out.println(student);
    }

个人理解:

autowire=“byName”:创建对象时,spring就找cn.com.Ycy.spring.Beans.student的类的引用类型属性名
在用这个引用类型名去找和这个值相同的id

2、byType:按类型注入
Java类中的引用类型的数据类型和Spring容器中(配置文件)的class是同源的关系,这样才可以赋值给引用类型。
同源关系:
  1. java类中的引用类型的数据类型和bean的class的值是一样的
  2. java类中的引用类型的数据类型和bean的class的值是父子关系的
  3. java类中的引用类型的数据类型和bean的class的值是接口和实现类关系
    就好像是这样的关系
    private school schools = new xxx();
    1. school school = new school();
    2. school school = new primarySchool();(父子关系)
    2. school school = new schoolImp();接口和实现类关系

    分析:

	<bean id="student2" class="cn.com.Ycy.spring.Beans.student" autowire="byType">
		<property name="name" value="王二"/>
		<property name="age" value="21"/>
	</bean>
	<bean id="mySchool" class="cn.com.Ycy.spring.Beans.school">
		<property name="name" value="北京大学"/>
		<property name="address" value="北京"/>
		<property name="id" value="0052"/>
	</bean>
public class student {
	private String name;
	private int age;
	private school schools;
}
	就是把
<bean id="mySchool" class="cn.com.Ycy.spring.Beans.school">
	<property name="name" value="北京大学"/>
	<property name="address" value="北京"/>
	<property name="id" value="0052"/>
</bean>
这个赋值给private school school
	private school school = 
<bean id="mySchool" class="cn.com.Ycy.spring.Beans.school">
	<property name="name" value="北京大学"/>
	<property name="address" value="北京"/>
 	<property name="id" value="0052"/>
</bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值