1.创建ioc容器对象
在获取我们配置文件中的bean中的对象时,需要先创建ioc容器对象读取对应的配置文件。
// 1.创建ioc容器对象
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext();
applicationContext.setConfigLocations("spring-03.xml");
applicationContext.refresh(); // ioc和di的动作
2.读取ioc容器中的组件
方案1:直接根据beanId获取
HappyComponent happyComponent = (HappyComponent) applicationContext.getBean("happyComponent");
这种方式的返回值是Object,得到的对象需要强转才能使用【不推荐使用】
方案2:根据beanId,同时指定bean的类型
HappyComponent happyComponent1 = applicationContext.getBean("happyComponent", HappyComponent.class);
这种方式就是在getBean的参数中多传一个Bean的类型,这样返回值就是对应的传入的类的类型
方案3:直接根据类型获取
HappyComponent happyComponent2 = applicationContext.getBean(HappyComponent.class);
注意:根据bean的类型获取,同一个类型,在ioc容器中只能有一个bean!如果ioc容器存在多个同类型的Bean 则会报错:NoUniqueBeanDefinitionException。ioc的配置一定是实现类,但是可以根据接口类型获取值。
这句话如何理解呢?因为我们是根据Bean的类型获取的对象,如果一个配置文件中有多个同一类型的Bean对象,那它就不知道我们到底需要哪一个,所以会报错。
ioc的配置一定是实现类,但是可以根据接口类型获取值:
我们使HappyComponent实现B接口
public interface B {
void doWork();
}
public class HappyComponent implements B{
//默认包含无参数构造函数
public void doWork() {
System.out.println("HappyComponent.doWork");
}
}
spring的配置文件无需修改
<bean id="happyComponent" class="com.atguigu.ioc_03.HappyComponent"></bean>
切记:ioc的配置一定是实现类!因为它才是真正需要进行实例化的对象!不能是接口!但是可以根据接口类型来获取对象值!
// 方案3:直接根据类型获取
B happyComponent2 = applicationContext.getBean(B.class);
happyComponent2.doWork();
它会这这样来匹配 getBean(类型).instanceof ioc 容器的类型 == true就OK
我们这里是getBean(A.class).instanceof(HappyComonent) == true
这里就是java的多态,父类的引用可以指向子类的对象。
热知识:这边获取到的对象都是一个对象,因为它是单例的