DI:依赖注入
依赖注入的3种方式:
1.set注入:通过setXxx()赋值;
2.构造器注入:通过构造方法赋值;
3.p命名注入:p命名空间赋值;
(4.自动装配只是用于引用类型即ref类型;)
一、set注入:
1.赋值,默认使用的是set方法;
2.依赖注入底层是通过反射技术实现的;
3.使用<property>关键字;
如:
//teacher对象
<bean id="teacher" class="org.entity.Teacher">
<property name="name" value="zs"></property>
<property name="age" value="23"></property>
</bean>
//course对象
<bean id="course" class="org.entity.Course">
<!-- xx.setCourseName("java")
courseName -> setCourseName()
set方式的依赖注入底层是通过反射技术实现的。
-->
<property name="courseName" value="java"></property>
<property name="courseHour" value="200"></property>
<!--将teacher对象注入到course对象中
xx.setTeacher(teacher);
-->
<property name="teacher" ref="teacher"></property>
</bean>
二、构造器注入:
1.实体类中要有无参、有参构造方法;
2.使用<constructor-arg>关键字;
3.实体类的有参构造方法中有几个属性就有几个<constructor-arg>;
2.若只填写value值,则<constructor-arg>对应顺序与构造方法中的顺序一致;
若要是对应顺序不一致方法:
a.使用index(值从0开始),代表该参数在有参构造方法中的顺序;
b.使用name,代表参数属性名;
c.使用type,代表参数值类型;
如:
//Teacher实体类有参构造方法
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
//teacher对象
<bean id="teacher" class="org.entity.Teacher">
<!--通过构造器赋值
顺序对应构造方法中的参数顺序
<constructor-arg value="ls"></constructor-arg>
<constructor-arg value="24"></constructor-arg>
顺序不对应,使用index,代表参数位置
<constructor-arg value="24" index="1"></constructor-arg>
<constructor-arg value="ls" index="0"></constructor-arg>
顺序不对应,使用type,代表参数类型[参数类型不相同可使用]
<constructor-arg value="24" type="int"></constructor-arg>
<constructor-arg value="ls" type="String"></constructor-arg>
-->
<!--顺序不对应,使用name,代表参数名-->
<constructor-arg value="24" name="age"></constructor-arg>
<constructor-arg value="ls" name="name"></constructor-arg>
</bean>
注:
在使用构造器注入中,若只有一个constructor-arg且只是用value时,无法判断value值得类型,
有字符串类型先给字符串类型赋值。
三、p命名注入:
1.引入p命名空间: xmlns:p="http://www.springframework.org/schema/p"
2.使用:
a.简单类型,p:属性名="属性值";
b.引用类型,p:属性名-ref="引用对象id值";
3.注意多个p赋值之间要有空格;
如:
//teacher对象
<bean id="teacher" class="org.entity.Teacher"
p:age="25" p:name="ww">
</bean>
//course对象
<bean id="course" class="org.entity.Course"
p:courseHour="300" p:courseName="hadoop" p:teacher-ref="teacher">
</bean>
(四、自动装配:只是用于ref类型参数)
1.设定autowire属性,在<bean>标签中
<bean id="course1" class="org.entity.Course" autowire="byName">
<property name="courseName" value="java"></property>
<property name="courseHour" value="200"></property>
</bean>
byName:自动在IOC容器中寻找其他bean的id值 = 该类中ref类型属性的属性名。(此方法在IOC中必须有且只有一个bean满足,否则报错)
byType:其他bean的类型(Class) = 该类中的ref类型属性的属性类型。(此方法在IOC中只有一个其他bean类型于ref类型相一致才能使用,没有或多于一个均报错)
constructor:其他bean的类型(Class) = 该类的构造方法参数的类型一致。
no:不使用自动装配。
2.IOC容器中所用bean统一设置,在<beans>标签中
<beans
...
default-autowire="byName"
>
此方式可以被<bean>中的autowire属性覆盖。
注:
自动装配虽然可以降低代码量,但是不建议经常使用,因为降低了代码的可读性。
各种集合类型的注入
List:
//类中
List<String> listElement;
//IOC中
<property name="listElement">
<list>
<value>足球L</value>
<value>篮球L</value>
<value>乒乓球L</value>
</list>
</property>
Array:
//类中
String[] arrayElement;
//IOC中
<property name="arrayElement">
<array>
<value>足球A</value>
<value>篮球A</value>
<value>乒乓球A</value>
</array>
</property>
Set:
//类中
Set<String> setElement;
//IOC中
<property name="setElement">
<set>
<value>足球S</value>
<value>篮球S</value>
<value>乒乓球S</value>
</set>
</property>
Map:
//类中
Map<String,String> mapElement;
//IOC中
<property name="mapElement">
<map>
<entry>
<key>
<value>soccer</value>
</key>
<value>足球M</value>
</entry>
<entry>
<key>
<value>basketball</value>
</key>
<value>篮球M</value>
</entry>
<entry>
<key>
<value>table tennis</value>
</key>
<value>乒乓球M</value>
</entry>
</map>
</property>
Properties:
//类中
Properties propsElement;
//IOC中
<property name="propsElement">
<props>
<prop key="soccer">足球P</prop>
<prop key="basketball">篮球P</prop>
<prop key="table tennis">乒乓球P</prop>
</props>
</property>
IOC容器的赋值:
默认使用的是属性对相应的set方法。(set注入)
1.如果是简单类型(8个基本+String),使用value, value="具体值";
2.如果是对象类型,使用ref, ref="需要引用容器中的对象id值";
因此,现实了对象与对象之间的依赖关系。
从IOC容器中获取对象(bean):
context.getBean("需要获取的bean的id值");
如:
//获取IOC容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//拿课程对象
Course course = (Course)context.getBean("course");