依赖查找
根据名称进行查找
- 实时查找
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核心编程思想。