依赖查找
根据名称进行查找
- 实时查找
BeanFactory beanFactory = new ClassPathXmlApplicationContext("beans.xml");
Object bean = beanFactory.getBean("personHolder");
System.out.println(bean);
xml如下:
<bean id="person"  class="pojo.Person">
    <property name="name" value="yong"></property>
    <property name="id" value="1001"></property>
</bean>
<bean id="personHolder"  class="pojo.PersonHolder" >
    <property name="city" value="BEIJING"></property>
    <property name="person" ref="person"></property>
</bean>
- 延迟查找
 所谓延迟查找其实就是我们使用到这个Bean的时候再去进行查找。
 通过xml配置的方式:
<!-- 这里指定了查找方式为延迟查找也就是说在需要用到这个bean的时候才会初始化 -->
<bean id="personHolder"  class="pojo.PersonHolder" lazy-init="true" init-method="init">
    <property name="city" value="BEIJING"></property>
    <property name="person" ref="person"></property>
</bean>
通过注解的方式:
@Bean
@Lazy
PersonHolder personHolder(Person person) {
   return new PersonHolder(person);
}
通过ObjectProvider的方式:
/**
* 也是延迟加载
* @param applicationContext
*/
private static void lookupIfAvailable(AnnotationConfigApplicationContext applicationContext) {
  ObjectProvider<PersonHolder> userObjectProvider = applicationContext.getBeanProvider(PersonHolder.class);
  PersonHolder personHolder = userObjectProvider.getIfAvailable(PersonHolder::createPersonHolder);
  System.out.println("当前 User 对象:" + personHolder);
}
public static void main(String[] args) {
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  context.register(LookUpLazyByNameAnnotation.class);
  context.refresh();
  lookupIfAvailable(context);
}
除了getIfAvailable, ObjectProvider还提供了getIfUnique方法。
根据类型查找
- 单个Bean
/**
 * 通过类型查找
 * @param beanFactory
 */
public static void lookUpByType(BeanFactory beanFactory) {
    Client bean = beanFactory.getBean(Client.class);
    System.out.println(bean);
}
- 集合类型的查找
/**
 * 集合查找 ListableBeanFactory 实现了这个接口就可以进行集合查找
 * @param beanFactory
 */
public static void lookUpCollectionByType(BeanFactory beanFactory) {
    if (beanFactory instanceof ListableBeanFactory) {
        ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
        Map<String, Client> beansOfType = listableBeanFactory.getBeansOfType(Client.class);
        System.out.println(beansOfType);
    }
}
根据注解查找
- 集合查找
/**
* 集合查找
* @param beanFactory
*/
public static void lookUpCollectionByAnnotation(BeanFactory beanFactory) {
   if (beanFactory instanceof ListableBeanFactory) {
       ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
       Map<String, Object> beansOfType = listableBeanFactory.getBeansWithAnnotation(Super.class);
       System.out.println(beansOfType);
   }
}
依赖查找详细版本
-  单一类型依赖查找(主要是基于BeanFactory) 
 根据Bean名称查找
-  getBean(String) 
-  Spring 2.5 覆盖默认参数:getBean(String, Object) 
 根据Bean类型查找
 Bean实时查找
 - Spirng 3.0getBean(Class)
 - Spring 4.1覆盖默认参数:getBean(Class, Object)
 Spring 5.1 Bean 延迟查找
 - getBeanProvider(Class)
 - getBeanProvider(ResolvableType)
 根据名称 + 类型查找 : getBean(Class, Name)
 JNDI - javax.naming.Context#lookup(javax.naming.Name)
 JavaBeans-java.beans.beancontext.BeanContext
  
-  集合类型依赖查找(Listable BeanFactory) 
-  根据 Bean 类型查找 - 获取同类型 Bean 名称列表 
    - getBeanNamesForType(Class)
- Spring 4.2 getBeanNamesForType(ResolvableType)
 
- 获取同类型 Bean 实例列表 
    - getBeansOfType(Class)以及重载方法
 
 
- 获取同类型 Bean 名称列表 
    
-  通过注解类型查找 
 Spring 3.0 获取标注类型 Bean 名称列表- getBeanNamesForAnnotation(Class<? extends Annotation>
 
-  Spring 3.0 获取标注类型 Bean 实例列表 - getBeansWithAnnotation(Class<? extends Annotation>)
 
-  Spring 3.0 获取指定名称+标注类型 Bean 实例 - findAnnotationOnBean(String, Class<? extends Annotation>)
 
-  层次性依赖查找接口-HierarchicalBeanFactory 
 双亲 BeanFactory:getParentBeanFactory()
 层次性查找
 根据 Bean 名称查找
 基于 containsLocalBean 方法实现
 根据 Bean 类型查找实例列表
 单一类型:BeanFactoryUtils#beanOfType
 集合类型:BeanFactoryUtils#beansOfTypelncludingAncestors
 根据 Java 注解查找名称列表
 BeanFactoryUtils#beanNamesForTypelncludingAncestors
public class Client {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context  = new AnnotationConfigApplicationContext();
        context.register(Client.class);
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 创建父亲工厂
        BeanFactory parent = createParent();
        // 设置父亲工厂
        beanFactory.setParentBeanFactory(parent);
        // 获取父工厂
        HierarchicalBeanFactory parentBeanFactory = (HierarchicalBeanFactory) beanFactory.getParentBeanFactory();
        // 父亲工厂查询
        disPlayLocalBean(parentBeanFactory, "user");
        // 当前工厂查询
        disPlayLocalBean(beanFactory, "user");
        // 双亲委派 当前工厂查不到 查父亲工厂
        displayContainsBean(beanFactory, "user");
        context.refresh();
        context.close();
    }
    public static BeanFactory createParent() {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions("beans.xml");
        return beanFactory;
    }
    public static void displayContainsBean(HierarchicalBeanFactory beanFactory  , String beanName) {
        boolean containsBean = containsBean(beanFactory, beanName);
        System.out.printf("当前工厂是否包含 %s",containsBean);
    }
    public static boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {
        BeanFactory parent = beanFactory.getParentBeanFactory();
        if (parent instanceof HierarchicalBeanFactory) {
            HierarchicalBeanFactory parentHierarchicalBeanFactory = HierarchicalBeanFactory.class.cast(parent);
            if (containsBean(parentHierarchicalBeanFactory, beanName)) {
                return true;
            };
        }
        return beanFactory.containsBean(beanName);
    }
    public static void disPlayLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {
        System.out.printf("当前工厂是否包含 %s", beanFactory.containsLocalBean(beanName));
        System.out.println();
    }
}
- 延迟查找
 主要涉及 ObjectFactory 和 ObjectProvider
public class Client {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context  = new AnnotationConfigApplicationContext();
        context.register(Client.class);
        context.refresh();
        lookupIfAvailable(context);
        context.close();
    }
    public static void lookupIfAvailable(ApplicationContext context) {
        ObjectProvider<User> beanProvider = context.getBeanProvider(User.class);
        User user = beanProvider.getIfAvailable(() -> User.createUser());
        System.out.println(user);
    }
}
- 安全查找
  
 也就是说单一查前两个会抛出异常,所以不安全,其它的方法获取Bean获取不到也不会抛出异常。
public class Client {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context  = new AnnotationConfigApplicationContext();
        context.register(Client.class);
        context.refresh();
        displayBeanFactoryGetBean(context);
    }
    /**
     * 会发生异常
     * @param beanFactory
     */
    public static void displayBeanFactoryGetBean(BeanFactory beanFactory) {
        try {
             beanFactory.getBean(User.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
- 内部依赖
  
  
  
- 依赖查找中的异常
  
 参考资料:Spring核心编程思想。



















