Spring Bean 注册方式小结

IOC容器

Spring的核心是一个IOC容器,管理着我们向容器注册的所有bean。下面我们来看下两种向容器注册bean的方式,

通过BeanDefinitionReader读取Spring Bean的配置文件,解析然后注册;通过ClassPathBeanDefinitionScanner直接扫描带有Spring Bean注解的Java类并注册;Reader

BeanDefinitionReader的使用方式如下,

import org.springframework.beans.factory.support.BeanDefinitionReader;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;import org.springframework.core.io.ClassPathResource;import org.springframework.core.io.Resource;{(String[] args) throws Exception {loadBeans();}() {BeanDefinitionRegistry registry = new DefaultListableBeanFactory();BeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);Resource resource = new ClassPathResource(“spring-beans.xml”);reader.loadBeanDefinitions(resource);System.out.println(((DefaultListableBeanFactory)registry).getBean(“foo”));}}

spring-beans.xml文件如下,

==>

上面我们以XmlBeanDefinitionReader为栗。需要将BeanDefinitionRegistry传给XmlBeanDefinitionReader,并且需要将配置文件构造成Resource,然后就可以调用BeanDefinitionReader#loadBeanDefinitions对bean配置文件进行加载,解析,最后向容器,也就是BeanDefinitionRegistry,注册bean了。loadBeanDefinitions方法最终是会来到方法,

/*** Register the bean definitions contained in the given DOM document.* Called by {@code loadBeanDefinitions}.* <p>Creates a new instance of the parser class and invokes* {@code registerBeanDefinitions} on it.* @param doc the DOM document* @param resource the resource descriptor (for context information)* @return the number of bean definitions found* @throws BeanDefinitionStoreException in case of parsing errors* @see #loadBeanDefinitions* @see #setDocumentReaderClass* @see BeanDefinitionDocumentReader#registerBeanDefinitions*/@SuppressWarnings(“deprecation”)(Document doc, Resource resource) throws BeanDefinitionStoreException {BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();documentReader.setEnvironment(getEnvironment());int countBefore = getRegistry().getBeanDefinitionCount();documentReader.registerBeanDefinitions(doc, createReaderContext(resource));return getRegistry().getBeanDefinitionCount() – countBefore;}

可以看到真正的工作是在里面完成的,,

/*** This implementation parses bean definitions according to the “spring-beans” XSD* (or DTD, historically).* <p>Opens a DOM Document; then initializes the default settings* specified at the {@code <beans/>} level; then parses the contained bean definitions.*/(Document doc, XmlReaderContext readerContext) {this.readerContext = readerContext;logger.debug(“Loading bean definitions”);Element root = doc.getDocumentElement();doRegisterBeanDefinitions(root);} /*** Register each bean definition within the given root {@code <beans/>} element.*/(Element root) {String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);if (StringUtils.hasText(profileSpec)) {String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);if (!getEnvironment().acceptsProfiles(specifiedProfiles)) {return;}}BeanDefinitionParserDelegate parent = this.delegate;this.delegate = createDelegate(this.readerContext, root, parent);preProcessXml(root);parseBeanDefinitions(root, this.delegate);postProcessXml(root);this.delegate = parent;} (Element root, BeanDefinitionParserDelegate delegate) {if (delegate.isDefaultNamespace(root)) {NodeList nl = root.getChildNodes();for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);if (node instanceof Element) {Element ele = (Element) node;if (delegate.isDefaultNamespace(ele)) {parseDefaultElement(ele, delegate);}else {delegate.parseCustomElement(ele);}}}}else {delegate.parseCustomElement(root);}}

最终是由BeanDefinitionParserDelegate来解析bean配置文件。 解析完成进行注册,因为两种方式实际上使用的注册方法都是同一个,因此我们放在后面再说,先来看下另一种方式。

Scanner

ClassPathBeanDefinitionScanner使用方式如下,

import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.beans.factory.support.DefaultListableBeanFactory;import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;{(String[] args) throws Exception {scanBeans();}() {BeanDefinitionRegistry registry = new DefaultListableBeanFactory();ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);scanner.scan(“me.kisimple.just4fun”);System.out.println(((DefaultListableBeanFactory)registry).getBean(“FooComponent”));}}坚韧是成功的一大要素,只要在门上敲得够久够大声,终会把人唤醒的。

Spring Bean 注册方式小结

相关文章:

你感兴趣的文章:

标签云: