Spring IoC容器之BeanFactory(二)

这是我参与更文挑战的第4天,活动详情查看:更文挑战

BeanFactory的对象注册与依赖绑定方式

与前面提到的IoC的绑定方式类似,也可以分为三种,分别是:直接编码、外部配置、注解。

1.直接编码方式

public static void main(String[] args)
{
    DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();
    BeanFactory container = (BeanFactory)bindViaCode(beanRegistry);
    FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider");
    newsProvider.getAndPersistNews();
}

public static BeanFactory bindViaCode(BeanDefinitionRegistry registry)
{
    AbstractBeanDefinition newsProvider = new RootBeanDefinition(FXNewsProvider.class,true);
    AbstractBeanDefinition newsListener = new RootBeanDefinition(DowJonesNewsListener.class,true);
    AbstractBeanDefinition newsPersister = new RootBeanDefinition(DowJonesNewsPersister.class,true);
    //将bean定义注册到容器中
    registry.registerBeanDefinition("djNewsProvider", newsProvider);
    registry.registerBeanDefinition("djListener", newsListener);
    registry.registerBeanDefinition("djPersister", newsPersister);
    //指定依赖关系
    //1.可以通过构造方法注入
    ConstructorArgumentValues argValues = new ConstructorArgumentValues();
    argValues.addIndexedArgumentValue(0, newsListener);
    argValues.addIndexedArgumentValue(1, newsPersister);
    newsProvider.setConstructorArgumentValues(argValues);
    /**
    *2.也可以通过setter方法注入
    *MutablePropertyValues propertyValues = new MutablePropertyValues();
    *propertyValues.addPropertyValues(new PropertyValue("newsListener", newsListener));
    *propertyValues.addPropertyValues(new PropertyValue("newPersister", newsPersister));
    newsProvider.setPropertyValues(propertyValues);
    **/
    //绑定完成
    return (BeanFactory)registry;
}
复制代码

BeanFactory只是一个接口,最终需要一个该接口的实现来进行实际的Bean管理,DefaultListableBeanFactory就是这么一个比较通用的BeanFactory实现类。DefaultListableBeanFactory除了间接地实现了BeanFactory接口,还实现了BeanDefinitionRegistry接口,该接口才是在BeanFactory的实现中担当Bean注册管理的角色。基本上,BeanFactory接口只定义如何访问容器内管理Bean的方法,各个BeanFactory的具体实现类负责具体Bean的注册以及管理工作。BeanDefinitionRegistry接口定义抽象了Bean的注册逻辑。通常情况下,具体的BeanFactory实现类会实现这个接口来管理Bean的注册。它们之间的关系如下所示:

IMG_0078(20210611-110713)

现在我们在回头上面这段绑定代码,就有“柳暗花明”的感觉了。

1.在main方法中,首先构造一个DefaultListableBeanFactory作为BeanDefinitionRegistry,然后将其交给bindViaCode方法进行具体的对象注册,最后执行相应逻辑。

2.在bindViaCode方法中,首先针对相应的业务对象构造与其相应的BeanDefinition,使用了RootBeanDefinition作为BeanDefinition的实现类。构造完成后,将这些BeanDefinition注册到通过方法参数传进来的BeanDefinitionRegistry中。之后,因为采用的是构造方法注入,所以需要ConstructorArgumentValues为其注入相关依赖。

2.外部配置文件方式

Spring的IoC容器支持两种配置文件格式:Properties文件格式和XML文件格式。

采用外部配置文件时,Spring的IoC容器有一个统一的处理方式。通常情况下,需要根据不同的外部配置文件格式,给出相应的BeanDefinitionReader实现类,由BeanDefinitionReader的相应实现类负责将相应的配置文件内容读取并映射到BeanDefinition,然后将映射后的BeanDefinition注册到一个BeanDefinitionRegistry,之后,BeanDefinitionRegistry即完成Bean的注册和加载。

对于Properties配置格式的加载,Spring提供了org.springframework.beans.factory.support.PropertiesBeanDefinitionReader类用于Properties配置格式的加载。所以,我们不用自己去实现BeanDefinitionReader,只要根据该类的读取规则,提供相应的配置文件即可。

对于XML配置格式的加载,Spring2.x之前,XML配置文件采用DTD(Document Type Definition)实现文档的格式约束。在2.x之后,引入了XSD(XML Schema Definition)的约束方式。

3.注解方式

使用@Autowired和@Component对相关类进行标记。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享