zoukankan      html  css  js  c++  java
  • Spring学习(一)

    文章内容来自:

    https://www.w3cschool.cn/wkspring/dcu91icn.html

    https://www.cnblogs.com/xiaoxi/p/5846416.html

    https://www.sohu.com/a/230831412_505825

    Spring 框架提供约 20 个模块,可以根据应用程序的要求来使用。

     

    核心容器

    核心容器由spring-core,spring-beans,spring-context,spring-context-support和spring-expression(SpEL,Spring表达式语言,Spring Expression Language)等模块组成。

    spring-core模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。

    spring-beans 模块提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。

    context模块建立在由core和 beans 模块的基础上建立起来的,它以一种类似于JNDI注册的方式访问对象。Context模块继承自Bean模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过Servelet容器)等功能。Context模块也支持Java EE的功能,比如EJB、JMX和远程调用等。ApplicationContext接口是Context模块的焦点。spring-context-support提供了对第三方库集成到Spring上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。

    spring-expression模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是JSP2.1规范中定义的统一表达式语言的扩展,支持set和get属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从Spring IoC容器检索对象,还支持列表的投影、选择以及聚合等。

    Spring BeanFactory 容器

    BeanFactory 是 Spring 的“心脏”。它就是 Spring IoC 容器的真面目。Spring 使用 BeanFactory 来实例化、配置和管理 Bean

    BeanFactory:是IOC容器的核心接口, 它定义了IOC的基本功能,我们看到它主要定义了getBean方法。getBean方法是IOC容器获取bean对象和引发依赖注入的起点。方法的功能是返回特定的名称的Bean。

    注意,BeanFactory 只能管理单例(Singleton)Bean 的生命周期。它不能管理原型(prototype,非单例)Bean 的生命周期。这是因为原型 Bean 实例被创建之后便被传给了客户端,容器失去了对它们的引用。

    BeanFactory有着庞大的继承、实现体系,有众多的子接口、实现类。来看一下BeanFactory的基本类体系结构(接口为主):

     具体:

      1、BeanFactory作为一个主接口不继承任何接口,暂且称为一级接口
      2、有3个子接口继承了它,进行功能上的增强。这3个子接口称为二级接口
      3、ConfigurableBeanFactory可以被称为三级接口,对二级接口HierarchicalBeanFactory进行了再次增强,它还继承了另一个外来的接口SingletonBeanRegistry
      4、ConfigurableListableBeanFactory是一个更强大的接口,继承了上述的所有接口,无所不包,称为四级接口
      (这4级接口是BeanFactory的基本接口体系。继续,下面是继承关系的2个抽象类和2个实现类:)
      5、AbstractBeanFactory作为一个抽象类,实现了三级接口ConfigurableBeanFactory大部分功能。
      6、AbstractAutowireCapableBeanFactory同样是抽象类,继承自AbstractBeanFactory,并额外实现了二级接口AutowireCapableBeanFactory
      7、DefaultListableBeanFactory继承自AbstractAutowireCapableBeanFactory,实现了最强大的四级接口ConfigurableListableBeanFactory,并实现了一个外来接口BeanDefinitionRegistry,它并非抽象类。
      8、最后是最强大的XmlBeanFactory,继承自DefaultListableBeanFactory,重写了一些功能,使自己更强大。

    总结:
      BeanFactory的类体系结构看似繁杂混乱,实际上由上而下井井有条,非常容易理解。

    再来看一下BeanFactory的源码:

    public interface BeanFactory {
        /**
         * 用来引用一个实例,或把它和工厂产生的Bean区分开,就是说,如果一个FactoryBean的名字为a,那么,&a会得到那个Factory
         */
        String FACTORY_BEAN_PREFIX = "&";
         /*
         * 四个不同形式的getBean方法,获取实例
         */
        Object getBean(String arg0) throws BeansException;
    
        <T> T getBean(String arg0, Class<T> arg1) throws BeansException;
    
        Object getBean(String arg0, Object... arg1) throws BeansException;
    
        <T> T getBean(Class<T> arg0) throws BeansException;
    
        <T> T getBean(Class<T> arg0, Object... arg1) throws BeansException;
    
        <T> ObjectProvider<T> getBeanProvider(Class<T> arg0);
    
        <T> ObjectProvider<T> getBeanProvider(ResolvableType arg0);
    
        boolean containsBean(String arg0); // 是否存在
    
        boolean isSingleton(String arg0) throws NoSuchBeanDefinitionException;
    
        boolean isPrototype(String arg0) throws NoSuchBeanDefinitionException; // 是否为原型(多实例)
    
        boolean isTypeMatch(String arg0, ResolvableType arg1) throws NoSuchBeanDefinitionException; 
    
        boolean isTypeMatch(String arg0, Class<?> arg1) throws NoSuchBeanDefinitionException;// 名称、类型是否匹配
    
        @Nullable
        Class<?> getType(String arg0) throws NoSuchBeanDefinitionException;
    
        String[] getAliases(String arg0); // 根据实例的名字获取实例的别名
    }

    具体:
      1、4个获取实例的方法。getBean的重载方法。
      2、4个判断的方法。判断是否存在,是否为单例、原型,名称类型是否匹配。
      3、1个获取类型的方法、一个获取别名的方法。根据名称获取类型、根据名称获取别名。一目了然!
    总结:
      这10个方法,很明显,这是一个典型的工厂模式的工厂接口。

    BeanFactory最常见的实现类为XmlBeanFactory,可以从classpath或文件系统等获取资源。

    第一步利用框架提供的 XmlBeanFactory() API 去生成工厂 bean, 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件。XmlBeanFactory() API 负责创建并初始化所有的对象,即在配置文件中提到的 bean。

    第二步利用第一步生成的 bean 工厂对象的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象,该对象最后可以用于实际的对象。一旦得到这个对象,你就可以利用这个对象来调用任何方法。

    1. XmlBeanFactory通过Resource装载Spring配置信息冰启动IoC容器,然后就可以通过factory.getBean从IoC容器中获取Bean了。
    2. 通过BeanFactory启动IoC容器时,并不会初始化配置文件中定义的Bean,初始化动作发生在第一个调用时。
    3. 对于单实例(singleton)的Bean来说,BeanFactory会缓存Bean实例,所以第二次使用getBean时直接从IoC容器缓存中获取Bean。

    Spring ApplicationContext 容器

    ApplicationContext由BeanFactory派生而来,提供了更多面向实际应用的功能。在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置实现。

    BeanFactorty接口提供了配置框架及基本功能,但是无法支持spring的aop功能和web应用。而ApplicationContext接口作为BeanFactory的派生,因而提供BeanFactory所有的功能。而且ApplicationContext还在功能上做了扩展,相较于BeanFactorty,ApplicationContext还提供了以下的功能: 

    (1)MessageSource, 提供国际化的消息访问  
    (2)资源访问,如URL和文件  
    (3)事件传播特性,即支持aop特性
    (4)载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层 

    最常被使用的 ApplicationContext 接口实现:

    FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。

    ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。

    WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。

    ApplicationContext:是IOC容器另一个重要接口, 它继承了BeanFactory的基本功能, 同时也继承了容器的高级功能,如:MessageSource(国际化资源接口)、ResourceLoader(资源加载接口)、ApplicationEventPublisher(应用事件发布接口)等。

    以下是ApplicationContext的源码:

    public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
            MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
        @Nullable
        String getId();
    
        String getApplicationName();
    
        String getDisplayName();
    
        long getStartupDate();
    
        @Nullable
        ApplicationContext getParent();
    
        AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
    }

    第一步生成工厂对象。加载完指定路径下 bean 配置文件后,利用框架提供的 FileSystemXmlApplicationContext API 去生成工厂 bean。FileSystemXmlApplicationContext 负责生成和初始化所有的对象,比如,所有在 XML bean 配置文件中的 bean。

    第二步利用第一步生成的上下文中的 getBean() 方法得到所需要的 bean。 这个方法通过配置文件中的 bean ID 来返回一个真正的对象。一旦得到这个对象,就可以利用这个对象来调用任何方法。

    Context 初始化流程

    Spring的bean在什么时候实例化?

    第一:如果你使用BeanFactory,如XmlBeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该bean的时候实例化 。

    第二:如果你使用ApplicationContext作为Spring Bean的工厂类,则又分为以下几种情况:

    1. 如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该bean,并且将实例化的bean放在一个线程安全的 ConcurrentHashMap 结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取 。
    2. 如果bean的scope是singleton的,并且lazy-init为true,则该bean的实例化是在第一次使用该bean的时候进行实例化 。
    3. 如果bean的scope是prototype的,则该bean的实例化是在第一次使用该Bean的时候进行实例化 。

    待更新。。。

  • 相关阅读:
    IOS微信浏览器返回事件popstate监听
    图解用HTML5的popstate如何玩转浏览器历史记录
    如何在深层嵌套ngRepeat中获取不同层级的$index
    angular ng-repeat 如何实现嵌套
    AJAX的工作原理
    利用angular指令监听ng-repeat渲染完成后执行脚本
    AngularJS中$http服务的简单用法
    AngularJS的Filter用法详解
    angularJS发起$http.post请求后台收不到数据解决方案
    AngularJs的UI组件ui-Bootstrap分享(十四)——Carousel
  • 原文地址:https://www.cnblogs.com/dingpeng9055/p/11581212.html
Copyright © 2011-2022 走看看