系列目录
IOC——控制反转(一)
IOC(Inversion of Control)称之为控制反转,简单来说是将对象创建的权力、对象生命周期的管理过程交由Spring框架来处理,从此在开发过程中,不再需要关注对象的创建和生命周期的管理,而是在需要时由Spring框架来提供。
这种由Spring框架管理对象创建和生命周期的机制即是控制反转。
1. 实现原理
在初始化一个Spring容器时,Spring会去解析指定的XML文件,当解析到其中的
之后,当通过getBean方法从容器中获取对象时,根据传入的条件在内置的Map中寻找是否有匹配的键值,如果有则返回保存的对象,如果没有则抛出异常。
由此可知:
- 默认情况下,多次获取同一个id的bean,得到的将是同一个对象。
- 不可以配置多个id相同的bean
- 可以配置多个id不同但class相同的bean
2. IOC获取对象的方式
-
通过context.getBean()方法,传入id。
通过此方法获取对象返回的是Object类型,需要向下强转。 -
通过context.getBean()方法,传入class类型。
如果同一个类配置过多个bean,则在获取时会因为无法确定到底要获取哪个bean而抛出异常。
SpringIOC在通过class获取bean时,如果找不到该类型的bean,则会去检查是否存在该类型的子孙类型的bean,如果有则返回,如果找不到或找到多个则会抛出异常。
3. 别名标签
在Spring中提供了别名标签
4. 案例代码:
public class Person01 {
private String name;
private int age;
public void say(){
System.out.println("say sth。。。");
}
public void show(){
System.out.println("show sth。。。");
}
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 class son01 extends Person01 {
@Override
public void say(){
System.out.println("我是子对象");
}
}
public class Test1 {
@Test
public void test(){
//1.初始化Spring容器
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//2.通过Spring获取bean
Person01 p1 = (Person01) context.getBean("person");
System.out.println(p1);
p1.say();
p1.show();
p1.setName("xixi");
p1.setAge(11);
System.out.println(p1.getName());
System.out.println(p1.getAge());
/*证明是同一个对象*/
Person01 p2 = (Person01) context.getBean("person");
System.out.println(p2.getName());
System.out.println(p2.getAge());
/*证明:通过类型获取对象时,如果出现多个bean是同一种类型,抛错*/
try{
Person01 p3 = context.getBean(Person01.class);
}catch (Exception e){
e.printStackTrace();
System.out.println("找到多个类型");
}
//3.关闭容器
((ClassPathXmlApplicationContext)context).close();
}
@Test
public void test01(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext2.xml");
/*通过类型获取对象,如果没有,还会找到子对象,注意父子类无法同时配置*/
Person01 p4 = context.getBean(Person01.class);
p4.say();
/*实验别名*/
son01 myson = (son01)context.getBean("myson");
myson.say();
((ClassPathXmlApplicationContext)context).close();
}
@Test
public void test02(){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext3.xml");
/*通过类型获取不需要强转*/
Person01 pp = context.getBean(Person01.class);
pp.say();
((ClassPathXmlApplicationContext)context).close();
}
}
//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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="person" class="cn.work.domain.Person01"/>
<bean id="person01" class="cn.work.domain.Person01"/>
</beans>
//applicationContext2.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--<bean id="person" class="cn.work.domain.Person01"/>-->
<bean id="son" class="cn.work.domain.son01"/>
<alias alias="myson" name="son"/>
</beans>
//applicationContext3.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="cn.work.domain.Person01"/>
</beans>