主要接口
分析DefaultListableBeanFactory
类的层次结构,包含了ioc容器中的主要的接口和实现类
一、主要接口
BeanFactory
-
依赖查找
-
通过名称、类型、构造器参数查找bean
-
查找延迟初始化bean
-
查找bean的方式为“拉模式”(依赖注入为“推模式”)
-
-
判断bean名称和类型是否匹配
-
通过名称查询bean的类型
-
定义初始化方法标准顺序
- BeanNameAware's setBeanName
- BeanClassLoaderAware's setBeanClassLoader
- BeanFactoryAware's setBeanFactory
- EnvironmentAware's setEnvironment
- EmbeddedValueResolverAware's setEmbeddedValueResolver
- ResourceLoaderAware's setResourceLoader (only applicable when running in an application context)
- ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context)
- MessageSourceAware's setMessageSource (only applicable when running in an application context)
- ApplicationContextAware's setApplicationContext (only applicable when running in an application context)
- ServletContextAware's setServletContext (only applicable when running in a web application context)
- postProcessBeforeInitialization methods of BeanPostProcessors
- InitializingBean's afterPropertiesSet
- a custom init-method definition
- postProcessAfterInitialization methods of BeanPostProcessors
-
定义关闭容器时销毁方法的顺序
On shutdown of a bean factory, the following lifecycle methods apply:
- postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
- DisposableBean's destroy
- a custom destroy-method definition
示例:
private static void s3_21() {
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("s3/s3-bean.xml");
BeanFactory beanFactory = defaultListableBeanFactory;
// 1. 依赖查找
// 通过名称查找
Object bean1 = beanFactory.getBean("t5Service");
// 通过类型查找
T5Service t5Service1 = beanFactory.getBean(T5Service.class);
// 通过名称和类型查找
T5Service t5Service2 = beanFactory.getBean("t5Service", T5Service.class);
// 通过名称和构造器参数查找(单例和原型不同,单例只有第一次实例化会使用构造器参数)
Object bean2 = beanFactory.getBean("t5Service", "test");
// 通过类型和构造器参数查找(单例和原型不同,单例只有第一次实例化会使用构造器参数)
T5Service t5Service3 = beanFactory.getBean(T5Service.class, "test");
// 延迟查找
ObjectProvider<T5Service> beanProvider = beanFactory.getBeanProvider(T5Service.class);
// 2. 类型匹配
final boolean isTypeMatch1 = beanFactory.isTypeMatch("t5Service", T5Service.class);
final boolean isTypeMatch2 = beanFactory.isTypeMatch("t5Service", ResolvableType.forType(T5Service.class));
// 3. 查询bean的类型
final Class<?> beanType = beanFactory.getType("t5Service");
}
测试初始化、销毁方法顺序
private static void s3_22() {
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("s3/s3-bean.xml");
// 注册通用注解处理器(包括初始化、销毁方法注解)
final CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor = new CommonAnnotationBeanPostProcessor();
commonAnnotationBeanPostProcessor.setBeanFactory(defaultListableBeanFactory);
defaultListableBeanFactory.addBeanPostProcessor(commonAnnotationBeanPostProcessor);
// 注册自定义的BeanPostProcess
defaultListableBeanFactory.addBeanPostProcessor(new CusBeanPostProcess());
// 创建bean
T5Service t5Service = defaultListableBeanFactory.getBean(T5Service.class);
// 销毁单例
defaultListableBeanFactory.destroySingletons();
}
自定义处理器
@Slf4j
public class CusBeanPostProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
printNo();
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
printNo();
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
private void printNo() {
final StackTraceElement stackTrace = new Throwable().getStackTrace()[1];
String name = stackTrace.getClassName() + "=>" + stackTrace.getMethodName();
log.info("方法名称【{}】,no=【{}】", name, NO.addAndGet(1));
}
}
定义测试bean
@Slf4j
public class T5Service implements
BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EmbeddedValueResolverAware,
InitializingBean, DisposableBean {
public static final AtomicInteger NO = new AtomicInteger(0);
private String data;
public T5Service() {
printNo();
}
public T5Service(String data) {
this.data = data;
log.info("带参构造器");
printNo();
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public void doSomething() {
log.info("name is " + getData());
}
@PostConstruct
public void initAnno() {
printNo();
}
public void initXml() {
printNo();
}
@PreDestroy
public void destroyAnno() {
printNo();
}
public void destroyXml() {
printNo();
}
private void printNo() {
final StackTraceElement stackTrace = new Throwable().getStackTrace()[1];
String name = stackTrace.getClassName() + "=>" + stackTrace.getMethodName();
log.info("方法名称【{}】,no=【{}】", name, NO.addAndGet(1));
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
printNo();
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
printNo();
}
@Override
public void setBeanName(String name) {
printNo();
}
@Override
public void destroy() throws Exception {
printNo();
}
@Override
public void afterPropertiesSet() throws Exception {
printNo();
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
printNo();
}
}
xml配置bean的元数据
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="t5Service" class="org.example.service.s3.T5Service" init-method="destroyXml" destroy-method="destroyXml"/>
</beans>
HierarchicalBeanFactory
接口增加了对层次结构的支持
- 获取父容器
- 判断当前工厂是否包含bean,不查询父工厂
示例:
private static void t3_31() {
// 父容器
DefaultListableBeanFactory parentBeanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(parentBeanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("s3/s3-parent-bean.xml");
// 当前容器
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader1 = new XmlBeanDefinitionReader(defaultListableBeanFactory);
xmlBeanDefinitionReader1.loadBeanDefinitions("s3/s3-bean.xml");
// 设置父容器
defaultListableBeanFactory.setParentBeanFactory(parentBeanFactory);
// 测试方法
HierarchicalBeanFactory hierarchicalBeanFactory = defaultListableBeanFactory;
final boolean isContain = hierarchicalBeanFactory.containsBean("t4Service");
final boolean isContain1 = hierarchicalBeanFactory.containsLocalBean("t4Service");
log.info("[{}-{}]", isContain, isContain1);
}
ListableBeanFactory
可列举的
-
通过类型、注解获取bean名称列表(不考虑层次结构)
-
通过类型、注解获取所有bean(不考虑层次结构)
-
BeanFactoryUtils
ConfigurableBeanFactory
增加设置、修改beanFactory的方法
- 注册外部单例bean,继承
SingletonBeanRegistry
接口 - 设置bean classloader、bean表达式解析器、类型转换器、嵌入的值解析器、bean后置处理器
- 注册scope、别名值解析器、依赖bean
- 注册别名
- 销毁bean
示例:
private static void s3_41() {
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("s3/s3-bean.xml");
// 注册通用注解处理器(包括初始化、销毁方法注解)
final CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor = new CommonAnnotationBeanPostProcessor();
commonAnnotationBeanPostProcessor.setBeanFactory(defaultListableBeanFactory);
defaultListableBeanFactory.addBeanPostProcessor(commonAnnotationBeanPostProcessor);
// 注册自定义的BeanPostProcess
defaultListableBeanFactory.addBeanPostProcessor(new CusBeanPostProcess());
ConfigurableBeanFactory configurableBeanFactory = defaultListableBeanFactory;
// 创建bean
T5Service t5Service = configurableBeanFactory.getBean(T5Service.class);
log.info("====================================================");
// 销毁bean,并不会清除单例缓存,只是调用销毁方法
configurableBeanFactory.destroyBean("t5Service", t5Service);
log.info("====================================================");
// 销毁所有单例bean
configurableBeanFactory.destroySingletons();
}
AutowireCapableBeanFactory
-
增加创建和填充外部bean实例的方法
- createBean
- autowireBean
- configureBean
-
增加对bean生命周期进行细粒度控制的专用方法
-
增加解析注入点的方法
- resolveNamedBean
- resolveBeanByName
- resolveDependency
示例:
private static void s3_51() {
DefaultListableBeanFactory defaultListableBeanFactory = buildBeanFactory();
registerBeanPostProcessor(defaultListableBeanFactory);
AutowireCapableBeanFactory autowireCapableBeanFactory = defaultListableBeanFactory;
// Ioc容器中不存在T6Service类的信息
// 创建和填充外部bean实例
T6Service t6Service1 = autowireCapableBeanFactory.createBean(T6Service.class);
log.info("[{}]", t6Service1);
// 处理被注解的属性和方法
T6Service t6Service2 = new T6Service();
autowireCapableBeanFactory.autowireBean(t6Service2);
log.info("[{}]", t6Service2);
// 使用Ioc中可用的bean元数据,来配置外部bean
T6Service t6Service3 = new T6Service();
final Object t6Service4 = autowireCapableBeanFactory.configureBean(t6Service3, "t5Service");
log.info("[{}]", t6Service3);
}
private static void s3_52() {
DefaultListableBeanFactory defaultListableBeanFactory = buildBeanFactory();
registerBeanPostProcessor(defaultListableBeanFactory);
AutowireCapableBeanFactory autowireCapableBeanFactory = defaultListableBeanFactory;
// Ioc容器中不存在T6Service类的信息
// 创建和填充外部bean实例;
// 对javabeans属性根据类型查找依赖进行注入;
// 若检查依赖,依赖不存在,则创建失败
Object t6Service1 = autowireCapableBeanFactory.createBean(T6Service.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
log.info("[{}]", t6Service1);
// 对存在Set方法属性进行依赖注入
final Object t6Service2 = autowireCapableBeanFactory.autowire(T6Service.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
log.info("[{}]", t6Service2);
// 对外部bean的属性进行依赖注入
T6Service t6Service3 = new T6Service();
autowireCapableBeanFactory.autowireBeanProperties(t6Service3, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
log.info("[{}]", t6Service3);
// 使用Ioc中可用的bean元数据,来配置外部bean
final T6Service t6Service4 = new T6Service();
autowireCapableBeanFactory.applyBeanPropertyValues(t6Service4, "t5Service");
log.info("[{}]", t6Service4);
}
private static void s3_53() throws Exception {
DefaultListableBeanFactory defaultListableBeanFactory = buildBeanFactory();
registerBeanPostProcessor(defaultListableBeanFactory);
AutowireCapableBeanFactory autowireCapableBeanFactory = defaultListableBeanFactory;
final DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(T6Service.class.getDeclaredField("t4Service1"), true);
final Object t4Service = autowireCapableBeanFactory.resolveBeanByName("t4Service", dependencyDescriptor);
log.info("[{}]", t4Service);
// 解析依赖
Object dependency = autowireCapableBeanFactory.resolveDependency(dependencyDescriptor, null);
log.info("[{}]", dependency);
}
ConfigurableListableBeanFactory
可列举的、可配置的
- 支持自动注入模式下,忽略特定javabean属性的注入
- 注册外部(非正常注册IoC的bean)依赖
- 判断某依赖是否有注入其他bean的能力
- 通过名称获取
BeanDefinition
- 支持预先实例化所有单例bean
示例:
private static void s3_61() {
DefaultListableBeanFactory defaultListableBeanFactory = buildBeanFactory();
registerBeanPostProcessor(defaultListableBeanFactory);
ConfigurableListableBeanFactory configurableListableBeanFactory = defaultListableBeanFactory;
final T6Service t6Service1 = new T6Service();
configurableListableBeanFactory.autowireBeanProperties(t6Service1, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
// 通过构造器参数、javabean属性类型、javabean属性名称自动注入时,忽略的依赖类型
configurableListableBeanFactory.ignoreDependencyType(T4Service.class);
// 通过javabean属性类型、javabean属性名称自动注入时,忽略的接口中的属性
// 如下:该接口setBeanFactory()即属性:beanFactory
configurableListableBeanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
final T6Service t6Service2 = new T6Service();
configurableListableBeanFactory.autowireBeanProperties(t6Service2, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
log.info("[{}]-[{}]", t6Service1, t6Service2);
// 注册可解析的依赖,依赖注入时可注入其他bean
configurableListableBeanFactory.registerResolvableDependency(T6Service.class, t6Service2);
// 实例化所有单例
configurableListableBeanFactory.preInstantiateSingletons();
}
网友评论