当前位置 博文首页 > 小小鱼儿小小林的博客:(2)Spring基础|什么是SpringIOC|简单认

    小小鱼儿小小林的博客:(2)Spring基础|什么是SpringIOC|简单认

    作者:[db:作者] 时间:2021-09-18 10:04

    上次说到Spring有两个核心组件,IOC(控制反转)和AOP(面向切面编程),今天就讲讲什么是Spring的IOC

    ?

    IOC:Inversion of Control 控制反转
    ? ? ? ?一种说法:对象之间的依赖关系,由容器在运行时依据配置文件动态的建立
    ? ? ? ?另一种说法:对象的控制器转移了,转到外部容器了,避免了代码的纠缠,代码更容易被维护,模板之间的耦合性降低,容易测试
    ?? ?IOC 控制反转意味着将你设计好的类交给容器去控制,而不是在类的内部进行控制,即控制权由应用代码中转到了外部容器


    ? ?IOC的两种实现方式:
    ? ? ? DI:Dependency Injection依赖注入,组件不做定位查询,只提供相应方法,由容器创建对象,并调用相应方法设置所需对象需要的组件
    ? ? ? DL:Dependency Lookup依赖查找,容器创建对象并提供回调接口和上下文环境给组件,需要时通过接口从容器中查找对象
    ?? ?依赖查找,现在使用不太多。(EJB使用的更多,将对象创建好后,放到容器中。)
    ?? ?
    ?? ?IOC解决:对象谁来创建的问题——》控制反转
    ?? ?DI解决:对象间的关系如何建立的问题。——》依赖注入


    ?org.springframework.beans及org.springframework.context包是IOC容器的基础,就是要使用spring,至少这两个包得存在

    ?

    SpringIOC核心API

    BeanFactory接口和容器

    BeanFactory是Spring中Bean容器,IoC的核心接口,主要用于处理Bean的初始化和配置,建立对象间的依赖关系

    BeanFactory.java 源码:?

    /*
     * Copyright 2002-2019 the original author or authors.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      https://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    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.
     *
     * <p>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).
     *
     * <p>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.
     *
     * <p>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.
     *
     * <p>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).
     *
     * <p>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.
     *
     * <p>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:
     * <ol>
     * <li>BeanNameAware's {@code setBeanName}
     * <li>BeanClassLoaderAware's {@code setBeanClassLoader}
     * <li>BeanFactoryAware's {@code setBeanFactory}
     * <li>EnvironmentAware's {@code setEnvironment}
     * <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
     * <li>ResourceLoaderAware's {@code setResourceLoader}
     * (only applicable when running in an application context)
     * <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
     * (only applicable when running in an application context)
     * <li>MessageSourceAware's {@code setMessageSource}
     * (only applicable when running in an application context)
     * <li>ApplicationContextAware's {@code setApplicationContext}
     * (only applicable when running in an application context)
     * <li>ServletContextAware's {@code setServletContext}
     * (only applicable when running in a web application context)
     * <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
     * <li>InitializingBean's {@code afterPropertiesSet}
     * <li>a custom init-method definition
     * <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
     * </ol>
     *
     * <p>On shutdown of a bean factory, the following lifecycle methods apply:
     * <ol>
     * <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
     * <li>DisposableBean's {@code destroy}
     * <li>a custom destroy-method definition
     * </ol>
     *
     * @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 {
    
    	/**
    	 * Used to dereference a {@link FactoryBean} instance and distinguish it from
    	 * beans <i>created</i> by the FactoryBean. For example, if the bean named
    	 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
    	 * will return the factory, not the instance returned by the factory.
    	 */
    	String FACTORY_BEAN_PREFIX = "&";
    
    
    	/**
    	 * Return an instance, which may be shared or independent, of the specified bean.
    	 * <p>This method allows a Spring BeanFactory to be used as a replacement for the
    	 * Singleton or Prototype design pattern. Callers may retain references to
    	 * returned objects in the case of Singleton beans.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to retrieve
    	 * @return an instance of the bean
    	 * @throws NoSuchBeanDefinitionException if there is no bean with the specified name
    	 * @throws BeansException if the bean could not be obtained
    	 */
    	Object getBean(String name) throws BeansException;
    
    	/**
    	 * Return an instance, which may be shared or independent, of the specified bean.
    	 * <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type
    	 * safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the
    	 * required type. This means that ClassCastException can't be thrown on casting
    	 * the result correctly, as can happen with {@link #getBean(String)}.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to retrieve
    	 * @param requiredType type the bean must match; can be an interface or superclass
    	 * @return an instance of the bean
    	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
    	 * @throws BeanNotOfRequiredTypeException if the bean is not of the required type
    	 * @throws BeansException if the bean could not be created
    	 */
    	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
    
    	/**
    	 * Return an instance, which may be shared or independent, of the specified bean.
    	 * <p>Allows for specifying explicit constructor arguments / factory method arguments,
    	 * overriding the specified default arguments (if any) in the bean definition.
    	 * @param name the name of the bean to retrieve
    	 * @param args arguments to use when creating a bean instance using explicit arguments
    	 * (only applied when creating a new instance as opposed to retrieving an existing one)
    	 * @return an instance of the bean
    	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
    	 * @throws BeanDefinitionStoreException if arguments have been given but
    	 * the affected bean isn't a prototype
    	 * @throws BeansException if the bean could not be created
    	 * @since 2.5
    	 */
    	Object getBean(String name, Object... args) throws BeansException;
    
    	/**
    	 * Return the bean instance that uniquely matches the given object type, if any.
    	 * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
    	 * but may also be translated into a conventional by-name lookup based on the name
    	 * of the given type. For more extensive retrieval operations across sets of beans,
    	 * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
    	 * @param requiredType type the bean must match; can be an interface or superclass
    	 * @return an instance of the single bean matching the required type
    	 * @throws NoSuchBeanDefinitionException if no bean of the given type was found
    	 * @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
    	 * @throws BeansException if the bean could not be created
    	 * @since 3.0
    	 * @see ListableBeanFactory
    	 */
    	<T> T getBean(Class<T> requiredType) throws BeansException;
    
    	/**
    	 * Return an instance, which may be shared or independent, of the specified bean.
    	 * <p>Allows for specifying explicit constructor arguments / factory method arguments,
    	 * overriding the specified default arguments (if any) in the bean definition.
    	 * <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
    	 * but may also be translated into a conventional by-name lookup based on the name
    	 * of the given type. For more extensive retrieval operations across sets of beans,
    	 * use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
    	 * @param requiredType type the bean must match; can be an interface or superclass
    	 * @param args arguments to use when creating a bean instance using explicit arguments
    	 * (only applied when creating a new instance as opposed to retrieving an existing one)
    	 * @return an instance of the bean
    	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
    	 * @throws BeanDefinitionStoreException if arguments have been given but
    	 * the affected bean isn't a prototype
    	 * @throws BeansException if the bean could not be created
    	 * @since 4.1
    	 */
    	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    
    	/**
    	 * Return a provider for the specified bean, allowing for lazy on-demand retrieval
    	 * of instances, including availability and uniqueness options.
    	 * @param requiredType type the bean must match; can be an interface or superclass
    	 * @return a corresponding provider handle
    	 * @since 5.1
    	 * @see #getBeanProvider(ResolvableType)
    	 */
    	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
    
    	/**
    	 * Return a provider for the specified bean, allowing for lazy on-demand retrieval
    	 * of instances, including availability and uniqueness options.
    	 * @param requiredType type the bean must match; can be a generic type declaration.
    	 * Note that collection types are not supported here, in contrast to reflective
    	 * injection points. For programmatically retrieving a list of beans matching a
    	 * specific type, specify the actual bean type as an argument here and subsequently
    	 * use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
    	 * @return a corresponding provider handle
    	 * @since 5.1
    	 * @see ObjectProvider#iterator()
    	 * @see ObjectProvider#stream()
    	 * @see ObjectProvider#orderedStream()
    	 */
    	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
    
    	/**
    	 * Does this bean factory contain a bean definition or externally registered singleton
    	 * instance with the given name?
    	 * <p>If the given name is an alias, it will be translated back to the corresponding
    	 * canonical bean name.
    	 * <p>If this factory is hierarchical, will ask any parent factory if the bean cannot
    	 * be found in this factory instance.
    	 * <p>If a bean definition or singleton instance matching the given name is found,
    	 * this method will return {@code true} whether the named bean definition is concrete
    	 * or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true}
    	 * return value from this method does not necessarily indicate that {@link #getBean}
    	 * will be able to obtain an instance for the same name.
    	 * @param name the name of the bean to query
    	 * @return whether a bean with the given name is present
    	 */
    	boolean containsBean(String name);
    
    	/**
    	 * Is this bean a shared singleton? That is, will {@link #getBean} always
    	 * return the same instance?
    	 * <p>Note: This method returning {@code false} does not clearly indicate
    	 * independent instances. It indicates non-singleton instances, which may correspond
    	 * to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly
    	 * check for independent instances.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to query
    	 * @return whether this bean corresponds to a singleton instance
    	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
    	 * @see #getBean
    	 * @see #isPrototype
    	 */
    	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
    	/**
    	 * Is this bean a prototype? That is, will {@link #getBean} always return
    	 * independent instances?
    	 * <p>Note: This method returning {@code false} does not clearly indicate
    	 * a singleton object. It indicates non-independent instances, which may correspond
    	 * to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly
    	 * check for a shared singleton instance.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to query
    	 * @return whether this bean will always deliver independent instances
    	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
    	 * @since 2.0.3
    	 * @see #getBean
    	 * @see #isSingleton
    	 */
    	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
    	/**
    	 * Check whether the bean with the given name matches the specified type.
    	 * More specifically, check whether a {@link #getBean} call for the given name
    	 * would return an object that is assignable to the specified target type.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to query
    	 * @param typeToMatch the type to match against (as a {@code ResolvableType})
    	 * @return {@code true} if the bean type matches,
    	 * {@code false} if it doesn't match or cannot be determined yet
    	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
    	 * @since 4.2
    	 * @see #getBean
    	 * @see #getType
    	 */
    	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
    
    	/**
    	 * Check whether the bean with the given name matches the specified type.
    	 * More specifically, check whether a {@link #getBean} call for the given name
    	 * would return an object that is assignable to the specified target type.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to query
    	 * @param typeToMatch the type to match against (as a {@code Class})
    	 * @return {@code true} if the bean type matches,
    	 * {@code false} if it doesn't match or cannot be determined yet
    	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
    	 * @since 2.0.1
    	 * @see #getBean
    	 * @see #getType
    	 */
    	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
    
    	/**
    	 * Determine the type of the bean with the given name. More specifically,
    	 * determine the type of object that {@link #getBean} would return for the given name.
    	 * <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates,
    	 * as exposed by {@link FactoryBean#getObjectType()}.
    	 * <p>Translates aliases back to the corresponding canonical bean name.
    	 * Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the name of the bean to query
    	 * @return the type of the bean, or {@code null} if not determinable
    	 * @throws NoSuchBeanDefinitionException if there is no bean with the given name
    	 * @since 1.1.2
    	 * @see #getBean
    	 * @see #isTypeMatch
    	 */
    	@Nullable
    	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    
    	/**
    	 * Return the aliases for the given bean name, if any.
    	 * All of those aliases point to the same bean when used in a {@link #getBean} call.
    	 * <p>If the given name is an alias, the corresponding original bean name
    	 * and other aliases (if any) will be returned, with the original bean name
    	 * being the first element in the array.
    	 * <p>Will ask the parent factory if the bean cannot be found in this factory instance.
    	 * @param name the bean name to check for aliases
    	 * @return the aliases, or an empty array if none
    	 * @see #getBean
    	 */
    	String[] getAliases(String name);
    
    }
    

    ?

    定义了如下方法:
       Object getBean(String name) //根据指定名称返回一个Bean实例
    
       <T> T getBean(Class<T> requiredType)  //返回一个与给定Class唯一匹配的Bean实例
    
       <T> T getBean(String name, Class<T> requiredType)
    
       Object getBean(String name, Object... args)
    
       Class<?> getType(String name)       //得到名称为name的Bean的Class对象
       
       boolean isPrototype(String name)   //判断名称为name的Bean是否是原型,即是否总是返回一个新实例
       boolean isSingleton(String name)   //判断名称为name的Bean是否是单例
    
       boolean containsBean(String name)  //判断是否包含给定名称的Bean实例
    
       boolean isTypeMatch(String name, Class<?> targetType)  //判断名称为name的Bean实例是否为targetType类型
       String[] getAliases(String name)  //如果名称为name的Bean有别名返回

    ?

    ApplicationContext接口和容器

    该接口继承于BeanFactory,增强了BeanFactory,提供了事务处理AOP,国际化,事件传递

    ?

    ?

    cs