IoC:获取对象方式的改变(由主动变被动)
- 好的获取资源的解决方案
- 由容器主动将资源推送到它所管理的组件里,组件要有接受资源的方式
- 查找被动形式
applicationContext.xml
<beans>
<!-- 实例化对象就是把对象放入spring容器中,通过bean元素配置 -->
<!-- 1.当知道id属性值时 可以通过getBean(”id值“)来获取对象,id值是不能重复
2.当没有指定id值时,可以通过getBean(*.class属性值也就是完全限定名)来获取对象
3.bean元素可以有任意个相同class属性的对象
-->
<bean id="javaCourse" class="com.spring.JavaCourse">
<property name="name" value="java课程"></property>
</bean>
<bean id="htmlCourse" class="com.spring.HtmlCourse"> </bean>
</beans>
//学习课程(一)
public void studyJavaCourse() {
Course c = new JavaCourse();
c.getCourse();
}
public void studyHtmlCourse() {
Course c = new HtmlCourse();
c.getCourse();
}
//(二)通过调用课程工厂
public void studyCourseByFactory(String name) {
CourseFactory factory = new CourseFactory();
Course c = factory.getCourse(name);
c.getCourse();
}
//(三)IOC方式实现
public void StudyCourseByIOC(String name){
**//1.实例化Spring对象
ApplicationContext ac=new ClassPathXmlApplicationContext("applictionContext.xml");**
/*
* 2.获取对象方式
* 1)getBean("bean元素的id值")
* 2)getBean(*.class) 反射
* 3)getBean("bean元素的id值",*.class)
*/ getBean放回Object类型
1. JavaCourse jc = (JavaCourse)ac.getBean(name);//强转 "javaCourse"
2. JavaCourse jc = (JavaCourse)ac.getBean(JavaCourse.class);//在这里不适合 有参数name
3. JavaCourse jc = (JavaCourse)ac.getBean(name,JavaCourse.class);
jc.getCourse();
}
DI(依赖注入)
常用两种方式:1.setter方法注入;(把get方法注释了不会报错) 2.构造方式注入
1.setter方法注入
private String sno;// 学号
private JavaCourse jc;
public void setSno(String sno) {
this.sno = sno;
}
<!-- 1.setter方法注入 -->
<bean id="student" class="com.spring.Student">
<!-- 通过property中value属性或者value子元素都可以实现想某一个属性注入值 -->
1). <!-- <property name="sno" value="0217"></property> --> //null
2).<property name="sno" >
<value>0217</value>
<null></null> <!-- 对某一个属性赋值为null -->
</property>
<property name="name" value="许"></property>
<property name="age" value="19"></property>
<!-- ref属性可以指定参考对象,他的值是该对象在容器中id元素对应的值 -->
<property name="jc" ref="javaCourse"></property>
</bean>
结果:Student [sno=null, name=许, age=19, jc=com.spring.JavaCourse@527740a2]
2.构造方法注入
Student.java
public Student(String sno, String name, int age) {
super();
this.sno = sno;
this.name = name;
this.age = age;
}
<!--2.构造方式注入 -->
(1)<!-- 默认情况是按照构造方法属性依次注入 -->
<bean id="student1" class="com.spring.Student">
<constructor-arg value="1111"></constructor-arg>
<constructor-arg value="xwy"></constructor-arg>
<constructor-arg value="666"></constructor-arg>
(2) <!-- 通过index属性可以指定注入的属性,从0开始 -->
<constructor-arg value="1111" index=" 0"></constructor-arg>
</bean>
(3) <!-- 通过type属性可以指定注入順序-->
<constructor-arg value="1111" type="java.lang.String"></constructor-arg>
<constructor-arg value="666" type="int"></constructor-arg>
結果: Student [sno=1111, name=xwy, age=666]
测试类
public class TestDI {
public static void main(String[] args) {
// 实例化容器
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//1.使用setter方式注入
Student student = (Student) ac.getBean("student");
System.out.println(student);
//2.使用构造方法注入
Student student1 = (Student) ac.getBean("student1");
System.out.println(student1);
}
}
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) ac.getBean("student");
区别:
3.当实体的属性是集合类型时,该如何注入
有List集合和 Map集合(如果是Set就换成Set)
public class Student {
private List<Profession> ps;
private Map<String,Profession> pf;
public void setPs(List<Profession> ps) {
this.ps = ps;
}
public void setPf(Map<String, Profession> pf) {
this.pf = pf;
}
}
public class Profession {
private String name;
public void setName(String name) {
this.name = name;
}
}
<!-- 当实体的属性是集合类型时,该如何注入 -->
<bean id="javaCourse" class="com.spring.JavaCourse">
<property name="name" value="Java课程"></property>
</bean>
<bean id="ps2" class="com.spring.Profession">
<property name="name" value="团支书"></property>
</bean>
<bean id="ps1" class="com.spring.Profession">
<property name="name" value="班长"></property>
</bean>
<bean id="student" class="com.spring.Student">
<!-- 通过property中value属性或者value子元素都可以实现想某一个属性注入值 -->
<property name="sno" value="0217"></property>
<property name="name" value="许"></property>
<property name="age" value="19"></property>
<!-- ref属性可以指定参考对象,他的值是该对象在容器中id元素对应的值 -->
<property name="jc" ref="javaCourse"></property>
<!-- 属性类型是list集合 -->
<property name="ps">
<list>
<ref bean="ps1"></ref>
<ref bean="ps2"></ref>
</list>
</property>
//<!-- 属性类型是map集合 -->
<property name="pf">
<map>
<entry key="first" value-ref="ps1"></entry>
<entry key="second" value-ref="ps2"></entry>
</map>
</property>
</bean>
public class TestCollection {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
Student student=(Student) ac.getBean("student");
System.out.println(student);
}
Student [sno=0217, name=许, age=19, jc=com.spring.JavaCourse@3b0143d3, ps=[Profession [name=班长], Profession [name=团支书]]]
//Student [sno=0217, name=许, age=19, jc=com.spring.JavaCourse@369f73a2, ps=[Profession [name=班长], Profession [name=团支书]], pf={first=Profession [name=班长], second=Profession [name=团支书]}]
自动注入autowire
是否使用自动注入根据你想实现的功能,如果想把实体类中的类型中的全部类型注入该实体对象,那就使用自动注入;反之不使用,因为自动注入不灵活
<!-- autowire属性自动注入方式
byType:根据实体类中属性对应的类型
byName:根据实体类中属性名称 -->
<bean id="student" class="com.spring.Student" autowire="byType">