1. spring中的bean是怎么获取的?

       spring的核心是spring容器,spring中提供两种核心容器,分别是BeanFactory和ApplicationContext,其中用于管理Bean的就是BeanFactory。
BeanFactory是spring的一个基本接口,它负责配置、创建、管理bean。从代码层面来说,spring容器就是某个实现了BeanFactory接口的类的实例。它有一个常用的实现类是名称为DefaultListableBeanFactory。
所以,我们想获得容器中的bean对象,要用spring容器对象中实现BeanFactory接口的方法来获取。

BeanFactory接口有以下几个基本方法

  1. boolean containsBean(String name): 判断容器中是否含有id为name的bean实例,
  2. Class<?>getType(String name): 返回容器中id为name的bean实例的类型
  3. Object getBean(String name): 返回容器中id为name的bean实例
// 通过id方式获取对象
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = app.getBean("指定id名");

可以看到,通过id方式获取对象,返回的是Object类型,需要强制转换类型来获取指定类型。

  1. <T>T getBean(Class<T> requiredType): 返回容器中属于requiredType类型的、唯一的bean实例。
//  通过给定类型获取对象
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = app.getBean(Person.class);

这里解释一下唯一是什么意思:这里的唯一指的是,当用指定类型的方式获取spring容器中bean对象时,spring容器中的那个类型的bean只能声明一个!而不是说你只能写一次getBean(Book.class)的意思,你可以写很多很多个,当你没声明scope是多例的时候,你声明再多个也只是给你同一个对象。

举例说明
当我spring容器中声明了两个同样类型而id不同bean实例person1与person2时

<bean id="person1" class="com.test.pojo.Person" scope="prototype">
        <property name="name" value="Zhangsan"/>
        <property name="pet" ref="pet"/>
    </bean>

    <bean id="person2" class="com.test.pojo.Person" scope="prototype">
        <property name="name" value="Zhangsan"/>
        <property name="pet" ref="pet"/>
    </bean>

这种情况,只能用id或者id与类型的方式来获取bean对象,因为存在两个或多个类型相同的bean对象时,你用获取类型的方式来获取bean对象,spring容器并不知道你需要的是哪一个,所以会报错。

public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person1 = context.getBean(Person.class);
        System.out.println(person1);
//      如果spring容器中只有唯一的person类型bean的话,这么写是没毛病的
        Person person2 = context.getBean(Person.class);
        System.out.println(person2);
//        id方式获取
        Person person3 = (Person) context.getBean("person1");
        System.out.println(person3);
    }

No qualifying bean of type ‘com.test.pojo.Person’ available: expected single matching bean but found 2: person1,person2
翻译过来就是找到了两个都是person类型不知大你要用哪一个。

  1. <T>T getBean(String name,Class<T> requiredType): 返回容器中id为name并且属于requiredType类型的Bean实例。

用法:我输入指定的id,但是我不想强制转换了,直接给我返回指定类型吧。

Person person4 = context.getBean("person1",Person.class);

由于id的名称是唯一的,所以不存在同id但是不同类型这种情况,所以这个的getBean()方法的最常用的方式应该就是这样了吧。