[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型

[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型

The point of this approach is that the BeanFactory is a central registry of application components, and centralizes configuration of application components (no more do individual objects need to read properties files, for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and Development" for a discussion of the benefits of this approach.

Note that it is generally better to rely on Dependency Injection ("push" configuration) to configure application objects through setters or constructors, rather than use any form of "pull" configuration like a BeanFactory lookup. Spring's Dependency Injection functionality is implemented using this BeanFactory interface and its subinterfaces.

Normally a BeanFactory will load bean definitions stored in a configuration source (such as an XML document), and use the org.springframework.beans package to configure the beans. However, an implementation could simply return Java objects it creates as necessary directly in Java code. There are no constraints on how the definitions could be stored: LDAP, RDBMS, XML, properties file, etc. Implementations are encouraged to support references amongst beans (Dependency Injection).

In contrast to the methods in ListableBeanFactory, all of the operations in this interface will also check parent factories if this is a HierarchicalBeanFactory. If a bean is not found in this factory instance, the immediate parent factory will be asked. Beans in this factory instance are supposed to override beans of the same name in any parent factory.

Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:

[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第1张图片

On shutdown of a bean factory, the following lifecycle methods apply:

1.postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
2.DisposableBean's destroy
3.a custom destroy-method definition

1. Bean 是什么?

完整的 bean schema 附在文末.




    
    
        
    


Bean 自动注入(autowire)的 4 中模式:

Controls whether bean properties are "autowired".
This is an automagical process in which bean references don't need
to be coded explicitly in the XML bean definition file, but rather the
Spring container works out dependencies. The effective default is "no".

There are 4 modes:

1. "no"
The traditional Spring default. No automagical wiring. Bean references
must be defined in the XML file via the  element (or "ref"
attribute). We recommend this in most cases as it makes documentation
more explicit.

Note that this default mode also allows for annotation-driven autowiring,
if activated. "no" refers to externally driven autowiring only, not
affecting any autowiring demands that the bean class itself expresses.

2. "byName"
Autowiring by property name. If a bean of class Cat exposes a "dog"
property, Spring will try to set this to the value of the bean "dog"
in the current container. If there is no matching bean by name, nothing
special happens.

3. "byType"
Autowiring if there is exactly one bean of the property type in the
container. If there is more than one, a fatal error is raised, and
you cannot use byType autowiring for that bean. If there is none,
nothing special happens.

4. "constructor"
Analogous to "byType" for constructor arguments. If there is not exactly
one bean of the constructor argument type in the bean factory, a fatal
error is raised.

Note that explicit dependencies, i.e. "property" and "constructor-arg"
elements, always override autowiring.

Note: This attribute will not be inherited by child bean definitions.
Hence, it needs to be specified per concrete bean definition. It can be
shared through the 'default-autowire' attribute at the 'beans' level
and potentially inherited from outer 'beans' defaults in case of nested
'beans' sections (e.g. with different profiles).

2. Bean 的领域模型: BeanDefinition

[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第2张图片
  • A BeanDefinition describes a bean instance, which has property values,
  • constructor argument values, and further information supplied by
  • concrete implementations.
package org.springframework.beans.factory.config;

import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

/**
 * A BeanDefinition describes a bean instance, which has property values,
 * constructor argument values, and further information supplied by
 * concrete implementations.
 *
 * 

This is just a minimal interface: The main intention is to allow a * {@link BeanFactoryPostProcessor} to introspect and modify property values * and other bean metadata. * * @author Juergen Hoeller * @author Rob Harrop * @since 19.03.2004 * @see ConfigurableListableBeanFactory#getBeanDefinition * @see org.springframework.beans.factory.support.RootBeanDefinition * @see org.springframework.beans.factory.support.ChildBeanDefinition */ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement { }

3. BeanFactory

org.springframework.beans.factory
Interface BeanFactory

public interface BeanFactory
The root interface for accessing a Spring bean container. This is the basic client view of a bean container; further interfaces such as ListableBeanFactory and ConfigurableBeanFactory are available for specific purposes.
This interface is implemented by objects that hold a number of bean definitions, each uniquely identified by a String name. Depending on the bean definition, the factory will return either an independent instance of a contained object (the Prototype design pattern), or a single shared instance (a superior alternative to the Singleton design pattern, in which the instance is a singleton in the scope of the factory).

The root interface for accessing a Spring bean container .

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

/**
 * The root interface for accessing a Spring bean container.
 * This is the basic client view of a bean container;
 * further interfaces such as {@link ListableBeanFactory} and
 * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
 * are available for specific purposes.
 *
 * 

This interface is implemented by objects that hold a number of bean definitions, * each uniquely identified by a String name. Depending on the bean definition, * the factory will return either an independent instance of a contained object * (the Prototype design pattern), or a single shared instance (a superior * alternative to the Singleton design pattern, in which the instance is a * singleton in the scope of the factory). Which type of instance will be returned * depends on the bean factory configuration: the API is the same. Since Spring * 2.0, further scopes are available depending on the concrete application * context (e.g. "request" and "session" scopes in a web environment). * *

The point of this approach is that the BeanFactory is a central registry * of application components, and centralizes configuration of application * components (no more do individual objects need to read properties files, * for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and * Development" for a discussion of the benefits of this approach. * *

Note that it is generally better to rely on Dependency Injection * ("push" configuration) to configure application objects through setters * or constructors, rather than use any form of "pull" configuration like a * BeanFactory lookup. Spring's Dependency Injection functionality is * implemented using this BeanFactory interface and its subinterfaces. * *

Normally a BeanFactory will load bean definitions stored in a configuration * source (such as an XML document), and use the {@code org.springframework.beans} * package to configure the beans. However, an implementation could simply return * Java objects it creates as necessary directly in Java code. There are no * constraints on how the definitions could be stored: LDAP, RDBMS, XML, * properties file, etc. Implementations are encouraged to support references * amongst beans (Dependency Injection). * *

In contrast to the methods in {@link ListableBeanFactory}, all of the * operations in this interface will also check parent factories if this is a * {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance, * the immediate parent factory will be asked. Beans in this factory instance * are supposed to override beans of the same name in any parent factory. * *

Bean factory implementations should support the standard bean lifecycle interfaces * as far as possible. The full set of initialization methods and their standard order is: *

    *
  1. BeanNameAware's {@code setBeanName} *
  2. BeanClassLoaderAware's {@code setBeanClassLoader} *
  3. BeanFactoryAware's {@code setBeanFactory} *
  4. EnvironmentAware's {@code setEnvironment} *
  5. EmbeddedValueResolverAware's {@code setEmbeddedValueResolver} *
  6. ResourceLoaderAware's {@code setResourceLoader} * (only applicable when running in an application context) *
  7. ApplicationEventPublisherAware's {@code setApplicationEventPublisher} * (only applicable when running in an application context) *
  8. MessageSourceAware's {@code setMessageSource} * (only applicable when running in an application context) *
  9. ApplicationContextAware's {@code setApplicationContext} * (only applicable when running in an application context) *
  10. ServletContextAware's {@code setServletContext} * (only applicable when running in a web application context) *
  11. {@code postProcessBeforeInitialization} methods of BeanPostProcessors *
  12. InitializingBean's {@code afterPropertiesSet} *
  13. a custom init-method definition *
  14. {@code postProcessAfterInitialization} methods of BeanPostProcessors *
* *

On shutdown of a bean factory, the following lifecycle methods apply: *

    *
  1. {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors *
  2. DisposableBean's {@code destroy} *
  3. a custom destroy-method definition *
* * @author Rod Johnson * @author Juergen Hoeller * @author Chris Beams * @since 13 April 2001 * @see BeanNameAware#setBeanName * @see BeanClassLoaderAware#setBeanClassLoader * @see BeanFactoryAware#setBeanFactory * @see org.springframework.context.ResourceLoaderAware#setResourceLoader * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher * @see org.springframework.context.MessageSourceAware#setMessageSource * @see org.springframework.context.ApplicationContextAware#setApplicationContext * @see org.springframework.web.context.ServletContextAware#setServletContext * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization * @see InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization * @see DisposableBean#destroy * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName */ public interface BeanFactory

数据结构:

[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第3张图片

[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第4张图片
[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第5张图片

DefaultListableBeanFactory

DefaultListableBeanFactory 模型中的核心属性:

    /** Map from dependency type to corresponding autowired value. */
    private final Map, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

    /** Map of bean definition objects, keyed by bean name. */
    private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);

    /** Map of singleton and non-singleton bean names, keyed by dependency type. */
    private final Map, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);

    /** Map of singleton-only bean names, keyed by dependency type. */
    private final Map, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);

    /** List of bean definition names, in registration order. */
    private volatile List beanDefinitionNames = new ArrayList<>(256);

    /** List of names of manually registered singletons, in registration order. */
    private volatile Set manualSingletonNames = new LinkedHashSet<>(16);

    /** Cached array of bean definition names in case of frozen configuration. */
    @Nullable
    private volatile String[] frozenBeanDefinitionNames;

    /** Whether bean definition metadata may be cached for all beans. */
    private volatile boolean configurationFrozen = false;

XmlBeanFactory

    private static void withSpringXMLBeanFactory() {
        Resource resource = new ClassPathResource("beans.xml");
        BeanFactory beanFactory = new XmlBeanFactory(resource);
        HelloService helloService = (HelloService) beanFactory.getBean("helloService");
        String s1 = helloService.service1("Jack");
        String s2 = helloService.service2("Jobs");
        System.out.println(s1);
        System.out.println(s2);
    }

ApplicationContext

    private static void withSpringApplicationContext() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        HelloService helloService = (HelloService) applicationContext.getBean("helloService");
        String s1 = helloService.service1("Jack");
        String s2 = helloService.service2("Jobs");
        System.out.println(s1);
        System.out.println(s2);
    }
[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第6张图片

beanFactoryMonitor

[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第7张图片
/** Synchronization monitor for the internal BeanFactory. */
private final Object beanFactoryMonitor = new Object();
[ 成为架构师系列 ] 4. Spring Ioc 容器领域模型_第8张图片

附录

spring-beans.xsd

Spring XML Beans Schema, version 4.3
Authors: Juergen Hoeller, Rob Harrop, Mark Fisher, Chris Beams

This defines a simple and consistent way of creating a namespace
of JavaBeans objects, managed by a Spring BeanFactory, read by
XmlBeanDefinitionReader (with DefaultBeanDefinitionDocumentReader).

A bean instance can be a "singleton" (shared instance) or a "prototype"
(independent instance). Further scopes can be provided by extended
bean factories, for example in a web environment.

References among beans are supported, that is, setting a JavaBean property
or a constructor argument to refer to another bean in the same factory
(or an ancestor factory).

As alternative to bean references, "inner bean definitions" can be used.
Such inner beans do not have an independent lifecycle; they are typically
anonymous nested objects that share the scope of their containing bean.

There is also support for lists, sets, maps, and java.util.Properties
as bean property types or constructor argument types.





    

    
        
    

    
    
        
            
        
        
            
                 element.
                ]]>
            
        
    

    
    
        
             and other elements, typically the root element in the document.
    Allows the definition of default values for all nested bean definitions. May itself
    be nested for the purpose of defining a subset of beans with certain default values or
    to be registered only when certain profile(s) are active. Any such nested  element
    must be declared as the last element in the document.
            ]]>
        
        
            
                
                
                    
                    
                    
                    
                
                
            
            
                
                     element should be parsed. Multiple profiles
    can be separated by spaces, commas, or semi-colons.

    If one or more of the specified profiles are active at time of parsing, the 
    element will be parsed, and all of its  elements registered, <import>
    elements followed, etc.  If none of the specified profiles are active at time of
    parsing, then the entire element and its contents will be ignored.

    If a profile is prefixed with the NOT operator '!', e.g.

        

    indicates that the  element should be parsed if profile "p1" is active or
    if profile "p2" is not active.

    Profiles are activated in one of two ways:
        Programmatic:
            ConfigurableEnvironment#setActiveProfiles(String...)
            ConfigurableEnvironment#setDefaultProfiles(String...)

        Properties (typically through -D system properties, environment variables, or
        servlet context init params):
            spring.profiles.active=p1,p2
            spring.profiles.default=p1,p2
                    ]]>
                
            
            
                
                    
                
            
            
                
                    
                
            
            
                
                    
                
                
                    
                        
                        
                        
                        
                        
                    
                
            
            
                
                    
                
            
            
                
                    
                
            
            
                
                    
                
            
            
        
    

    
        
            
        
        
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
            
                
                
                
                
                
                
                
            
        
    

    
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                 element (or "ref"
    attribute). We recommend this in most cases as it makes documentation
    more explicit.

    Note that this default mode also allows for annotation-driven autowiring,
    if activated. "no" refers to externally driven autowiring only, not
    affecting any autowiring demands that the bean class itself expresses.

    2. "byName"
    Autowiring by property name. If a bean of class Cat exposes a "dog"
    property, Spring will try to set this to the value of the bean "dog"
    in the current container. If there is no matching bean by name, nothing
    special happens.

    3. "byType"
    Autowiring if there is exactly one bean of the property type in the
    container. If there is more than one, a fatal error is raised, and
    you cannot use byType autowiring for that bean. If there is none,
    nothing special happens.

    4. "constructor"
    Analogous to "byType" for constructor arguments. If there is not exactly
    one bean of the constructor argument type in the bean factory, a fatal
    error is raised.

    Note that explicit dependencies, i.e. "property" and "constructor-arg"
    elements, always override autowiring.

    Note: This attribute will not be inherited by child bean definitions.
    Hence, it needs to be specified per concrete bean definition. It can be
    shared through the 'default-autowire' attribute at the 'beans' level
    and potentially inherited from outer 'beans' defaults in case of nested
    'beans' sections (e.g. with different profiles).
                ]]>
            
            
                
                    
                    
                    
                    
                    
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
            
                
            
        
        
    

    
        
            
        
    

    
        
            
                
            
        
        
            
                
            
        
    

    
        
            
        
        
            
                
                    
                    
                
            
        
    

    
        
            
                
        
        
            
                
                
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                
            
            
                
                    
                
            
            
                
                    
                
            
            
                
                    
                
            
            
                
                    " element.
                    ]]>
                
            
            
                
                    ..." element.
                    ]]>
                
            
        
    

    
        
            
        
    

    
        
            
        
        
            
                
            
            
            
        
    

    
        
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
                
                    
                
            
            
                
                    
                
            
            
                
                    
                
            
        
    

    
        
            
        
        
            
            
                
                    
                
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
            
                
                    
                
            
        
    

    
        
            
        
        
            
        
    

    
    
        
            
            
                
                
                
                
                
                
                
                
                
                
                
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
    

    
        
            
        
        
            
                
                    
                        
                            
                        
                    
                
            
        
    

    
        
            
        
        
            
        
    

    
        
            
        
        
            
            
                
                    
                
            
        
    

    
        
            
            
                
                
                
                
                
                
                
                
                
                
                
                
            
        
        
            
                
            
        
        
            
                ".
                ]]>
            
        
        
            
                ..." element.
                ]]>
            
        
    

    

    
    
        
            
                
            
        
    

    
    
        
            
                
            
        
    

    
    
        
            
                
                    
                    
                        
                    
                
                
                    
                        
                    
                
            
        
    

    
    
        
            
            
        
        
            
                
            
        
        
            
                ".
                ]]>
            
        
        
            
                ..."
    element.
                ]]>
            
        
        
            
                ".
                ]]>
            
        
        
            
                ..." element.
                ]]>
            
        
    

    
    
        
            
                
                    
                        
                    
                
            
        
    

    
    
        
            
            
            
        
    



你可能感兴趣的:([ 成为架构师系列 ] 4. Spring Ioc 容器领域模型)