Spring中的set注入方法
作者:举个栗子?
IoC控制反转
控制反转(IoC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。
控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器,通过容器实现对象的创建,属性赋值,依赖的管理。IoC当前比较流行的实现方式是依赖注入(DI,Dependency Injection)
依赖注入DI
依赖注入DI是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
Spring 的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象之间依赖关系的管理。
Spring 框架使用依赖注入(DI)实现 IoC。
Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。
Spring 容器管理着容器中 Bean 之间的依赖关系,Spring 使用“依赖注入”的方式来管理 Bean 之间的依赖关系。
使用 IoC 实现对象之间的解耦和。
Spring中DI的实现
Spring中DI的实现有两种
1、在Spring配置文件中,使用标签和属性实现DI,称为基于XML的DI。
2、使用Spring中的注解来实现DI,称为基于注解的DI
基于XML的DI
bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。根据注入方式的不同,常用的有两类:set 注入、构造注入。
set注入
set 注入也叫设值注入,是指通过 setter 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。
根据属性的数据类型的不同,set注入又可以分为简单类型的set注入和引用类型的set注入。
简单类型的set注入
Spring中规定基本数据类型和String类型都是简单类型。
声明一个Student类
public class Student { private String name; private int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
在Spring的配置文件中声明需要添加到容器中的对象
<bean id="myStudent" class="com.xxx.package01.Student"> <!--id属性是自定义的对象名称,class属性是类的全限定名称--> <property name="name" value="zhangsan" /> <property name="age" value="20" /> <!--name是属性名,value是属性值--> </bean>
写一个测试类来测试DI
@Test public void test01(){ String config = "package01/applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(config); Student student = (Student) ac.getBean("myStudent"); System.out.println("Student = " + student); }
测试结果:
根据测试结果我们可以看出,spring通过DI将配置文件中声明的属性值成功赋给了容器中对象的属性。
引用类型的set注入
在以上代码的基础上,我们添加另外一个School类
public class School { private String name; private String address; public void setName(String name) { this.name = name; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
修改Student类,Student类的属性中包含了引用类型school
public class Student { private String name; private int age; private School school; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setSchool(School school) { this.school = school; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
在spring配置文件中声明Student对象和School对象
<!--声明Student对象--> <bean id="myStudent" class="com.xxx.package02.Student"> <property name="name" value="zhangsan" /> <property name="age" value="20" /> <property name="school" ref="mySchool" /> <!--name="属性名称" ref="引用类型的bean的id"--> </bean> <!--声明School对象--> <bean id="mySchool" class="com.xxx.package02.School"> <property name="name" value="北京大学" /> <property name="address" value="北京" /> </bean>
创建测试类
public class MyTest02 { @Test public void test01(){ String config = "package02/applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(config); Student myStudent = (Student) ac.getBean("myStudent"); System.out.println("Student = " + myStudent); } }
测试结果:
引用类型还可以实现自动注入
对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为标签设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属 性)。
根据自动注入判断标准的不同,可以分为两种:
- byName:根据名称自动注入
- byType: 根据类型自动注入
byName方式自动注入
当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,可使用byName 方式,让容器自动将被调用者 bean 注入给调用者 bean。
容器是通过调用者的 bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。
<!--声明Student对象--> <bean id="myStudent" class="com.xxx.package03.Student" autowire="byName"> <property name="name" value="zhangsan" /> <property name="age" value="20" /> </bean> <!--声明School对象--> <bean id="school" class="com.xxx.package03.School"> <property name="name" value="北京大学" /> <property name="address" value="北京" /> </bean>
byType方式自动注入
使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 bean 类的某引用类型属性类型同源。
即要么相同,要么有 is-a 关系(子类,或是实现类)。
但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。
<!--声明Student对象--> <bean id="myStudent" class="com.xxx.package03.Student" autowire="byType"> <property name="name" value="zhangsan" /> <property name="age" value="20" /> </bean> <!--声明School对象--> <bean id="mySchool" class="com.xxx.package03.School"> <property name="name" value="北京大学" /> <property name="address" value="北京" /> </bean>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。