标签:init 1.0 his .class div classes sso 处理 文档
本文是王福强所著<<spring揭秘>>一书的读书笔记
我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Provider提供两个功能对象的创建,依赖关系的管理。
只是,IoC容器这个词中,我们还得关注容器二字。它还包括了一些别的功能,例如以下图
ApplciationContext:除了拥有BeanFctory的所有功能外,它还提供了一些高级特性。
相应它所管理的对象,在容器启动的时候就把所有的bean都载入了,并且启动时须要的资源也比較多。
两个容器的关系例如以下:
我们看看BeanFactory的接口说明,都是些跟查询相关的方法。
FXNewsProvider newsProvider = new FXNewsProvider(); newsProvider.getAndPersistNews();在之前的章节里,我们就说了IoC模式的优点就是用户不用处理各个组件间的依赖问题了。
那谁来处理呢?丢给BeanFactory。
首先,我们用xml来说明依赖关系
<beans> <bean id="djNewsProvider" class="..FXNewsProvider"> <constructor-arg index="0"> <ref bean="djNewsListener"/> </constructor-arg> <constructor-arg index="1"> <ref bean="djNewsPersister"/> </constructor-arg> </bean> ... </beans>看看client的代码
BeanFactory container = new XmlBeanFactory(new ClassPathResource("配置文件路径")); FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider"); newsProvider.getAndPersistNews();至于XmlBeanFactory是个什么东西,大家看名字猜也能猜出来,就是一个实现了BeanFactoy且能从xml中读取依赖关系的对象嘛。
ApplicationContext container = new ClassPathXmlApplicationContext("配置文件路径"); FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider"); newsProvider.getAndPersistNews();OK,这次使用了ClassPathXmlApplicationContext,就是一个实现了ApplicationContext且能从xml中读取依赖关系的对象嘛。
再或者
ApplicationContext container = new FileSystemXmlApplicationContext("配置文件路径"); FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider"); newsProvider.getAndPersistNews();后两者有什么差别?
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.addPropertyValue(new ropertyValue("newsListener",newsListener)); propertyValues.addPropertyValue(new PropertyValue("newPersistener",newsPersister)); newsProvider.setPropertyValues(propertyValues); // 绑定完毕 return (BeanFactory)registry; }
我们看看上面几个对象的uml类图。
RootBeanDefinition与ChildBeanDefinition有什么差别?
java中的类是有继承关系,在xml中,bean包括一个parent属性。
RootBeanDefinition:一个bean就是一个顶级对象(没有parent)
ChildBeanDefinition:相应于一个子Bean定义。他是从一个已有的Bean继承而来
ChildBeanDefinitionl里面有一个私有变量parentName。
下来就是BeanDefinitionRegistry
BeanDefinitionRegistry也是一个接口,其方法例如以下:
/** Map of bean definition objects, keyed by bean name */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64); /** List of bean definition names, in registration order */ private final List<String> beanDefinitionNames = new ArrayList<String>();说实话,我不明确为什么还须要有一个beanDefinitionNames,beanDefinitionMap的key不就是beanname吗?
djNewsProvider.(class)=..FXNewsProvider # ----------通过构造方法注入的时候------------- djNewsProvider.$0(ref)=djListener djNewsProvider.$1(ref)=djPersister # ----------通过setter方法注入的时候--------- # djNewsProvider.newsListener(ref)=djListener # djNewsProvider.newPersistener(ref)=djPersister djListener.(class)=..impl.DowJonesNewsListener djPersister.(class)=..impl.DowJonesNewsPersister
public static void main(String[] args) { DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory(); BeanFactory container = (BeanFactory)bindViaPropertiesFile(beanRegistry); FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider"); newsProvider.getAndPersistNews(); } public static BeanFactory bindViaPropertiesFile(BeanDefinitionRegistry registry) { PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(registry); reader.loadBeanDefinitions("classpath:../../binding-config.properties"); return (BeanFactory)registry; }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ? "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="djNewsProvider" class="..FXNewsProvider"> <constructor-arg index="0"> <ref bean="djNewsListener"/> </constructor-arg> <constructor-arg index="1"> <ref bean="djNewsPersister"/> </constructor-arg> </bean> <bean id="djNewsListener" class="..impl.DowJonesNewsListener"> </bean> <bean id="djNewsPersister" class="..impl.DowJonesNewsPersister"> </bean> </beans>调用代码例如以下:
public static void main(String[] args) { DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory(); BeanFactory container = (BeanFactory)bindViaXMLFile(beanRegistry); FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider"); newsProvider.getAndPersistNews(); } public static BeanFactory bindViaXMLFile(BeanDefinitionRegistry registry) { XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry); reader.loadBeanDefinitions("classpath:../news-config.xml"); return (BeanFactory)registry; // 或者直接 //return new XmlBeanFactory(new ClassPathResource("../news-config.xml")); }跟上面的properties每什么差别,就是多了一个XmlBeanFactory。
@Component public class FXNewsProvider { @Autowired private IFXNewsListener newsListener; @Autowired private IFXNewsPersister newPersistener; public FXNewsProvider(IFXNewsListener newsListner,IFXNewsPersister newsPersister) { this.newsListener = newsListner; this.newPersistener = newsPersister; } ... } @Component public class DowJonesNewsListener implements IFXNewsListener { ... } @Component public class DowJonesNewsPersister implements IFXNewsPersister { ... }@Component 是告诉spring的扫描器:这是一个bean。
@Autowired 是告诉spring的扫描器:这里须要一个注入对象。
演示样例xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <context:component-scan base-package="cn.spring21.project.base.package"/> </beans>
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("配置文件路径"); FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("FXNewsProvider"); newsProvider.getAndPersistNews(); }
spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定
标签:init 1.0 his .class div classes sso 处理 文档
原文地址:http://www.cnblogs.com/mthoutai/p/7050561.html