Spring IoC 依赖查找
根据Bean 名称查找
实时查找
延迟查找
根据Bean 类型查找
单个Bean 对象
集合Bean 对象
根据Bean 名称+ 类型查找
根据Java 注解查找
单个Bean 对象
集合Bean 对象
代码示例
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.geekbang.thinking.in.spring.ioc.overview.dependency.lookup;
import org.geekbang.thinking.in.spring.ioc.overview.annotation.Super;
import org.geekbang.thinking.in.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Map;
/**
* 22 | Spring IoC依赖查找:依赖注入还不够吗?依赖查找存在的价值几何?
* 依赖查找示例, 具体的原理后面章节还会讲
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
* @since
*/
public class DependencyLookupDemo {
public static void main(String[] args) {
// 配置 XML 配置文件
// 启动 Spring 应用上下文
// 配置文件在 dependency-lookup-context.xml
// 这里作者建议, 配置文件最好放在元数据目录, 即 META-INF
BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
// 22-1.1 根据bean的名称查找, 实时查找
lookupInRealTime(beanFactory);
// 22-1.2 根据bean的名称查找, 延迟查找
lookupInLazy(beanFactory);
// 22-2.1 根据Bean类型查找, 单个Bean对象
lookupByType(beanFactory);
// 22-2.2 根据Bean类型查找, 集合Bean对象
lookupCollectionByType(beanFactory);
// 22-2.3 根据Bean 名称+ 类型查找, 不做演示,
// 就是调用getBean(String name, Class<T> requiredType)
// 22-4. 根据Java 注解查找对象
lookupByAnnotationType(beanFactory);
// lookupInRealTime(beanFactory);
// lookupInLazy(beanFactory);
}
/**
* 22-4. 根据Java 注解查找
* @param beanFactory
*/
private static void lookupByAnnotationType(BeanFactory beanFactory) {
if (beanFactory instanceof ListableBeanFactory) {
ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
// SuperUser 也需要在配置文件中注册
// 这里需要配置一个primary, 否则会报错, 因为有两个类
Map<String, User> users =
(Map) listableBeanFactory.getBeansWithAnnotation(Super.class);
System.out.println("查找标注 @Super 所有的 User 集合对象:" + users);
}
}
/**
* 22-2. 根据Bean类型查找
* 22-2.2 集合Bean对象
* @param beanFactory
*/
private static void lookupCollectionByType(BeanFactory beanFactory) {
if (beanFactory instanceof ListableBeanFactory) {
// 这里 ListableBeanFactory 接口后面会再讨论, 先用着
ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
// a Map with the matching beans, containing the bean names as keys
// and the corresponding bean instances as values
Map<String, User> users = listableBeanFactory.getBeansOfType(User.class);
System.out.println("查找到的所有的 User 集合对象:" + users);
}
}
/**
* 22-2. 根据Bean类型查找
* 22-2.1 单个Bean对象
* @param beanFactory
*/
private static void lookupByType(BeanFactory beanFactory) {
User user = beanFactory.getBean(User.class);
System.out.println("实时查找:" + user);
}
/**
* 22-1. 根据bean的名称查找
* 22-1.2 延迟查找
* 注意这个和 spring里面一个延迟加载的Bean 是两回事,
* 这里用到的 objectFactory 也要注册在配置文件内
*
* 延迟依赖查找主要用于获取 BeanFactory 后,不马上获取相关的 Bean,
* 比如在 BeanFactoryPostProcessor 接口中获取 ConfigurableListableBeanFactory 时,
* 不马上获取,降低 Bean 过早初始化的情况
*
* 这里有一个问题, ObjectFactory, FactoryBean 和 BeanFactory 三者区别是?
* ObjectFactory 对象并不是直接返回了实际的 Bean,而是一个 Bean 的查找代理。
* 当得到 ObjectFactory 对象时,相当于 Bean 没有被创建,
* 只有当 getObject() 方法时,才会触发 Bean 实例化等生命周期
*
* FactoryBean 是一种特殊的 Bean,需要注册到 IoC 容器,
* 通过容器 getBean 获取 FactoryBean#getObject() 方法的内容,
*
* BeanFactory#getBean 则是依赖查找,如果 Bean 没有初始化,那么将从底层查找或构建。
* @param beanFactory
*/
private static void lookupInLazy(BeanFactory beanFactory) {
// spring3.0 之前不支持泛型强转, java5 有的泛型
// 实际上ObjectFactory不会生成新的bean, 这是其与FactoryBean的一个重大区别
ObjectFactory<User> objectFactory =
(ObjectFactory<User>) beanFactory.getBean("objectFactory");
User user = objectFactory.getObject();
System.out.println("延迟查找:" + user);
}
/**
*
* 22-1. 根据bean的名称查找
* 22-1.1 实时查找
* 还记得最早使用xml文件, 使用id来注册bean的时光么?
* User类注册在配置文件里了
* @param beanFactory
*/
private static void lookupInRealTime(BeanFactory beanFactory) {
User user = (User) beanFactory.getBean("user");
System.out.println("实时查找:" + user);
}
}