zoukankan      html  css  js  c++  java
  • Preview of Spring-framework :Spring框架的预习和自我整理

    Spring简介 - 预习的自我整理

    1. What's Spring?

    Spring是一个从实际开发中抽取出来的框架,完成了大量开发中的通用步骤,留给开发者仅仅是与特定应用相关的部分,从而提高了企业应用开发的效率。

    Spring为企业应用的开发提供了一个轻量级的解决方案,包括:基于依赖注入的核心机制等等。

    Spring贯穿表现层、业务层、持久层。

    2. Spring的特点

    1)低侵入式设计,代码的污染极低;

    2)独立于各种应用服务器;

    3)Spring的DI容器降低了业务对象替换的复杂性,提高了组件之间的解耦;

    4)Spring的AOP (Aspect Oriented Programming,面向方面编程)支持允许将一些通用任务如安全、事务等进行集中式处理,从而提供更好的复用;

    5)Spring的ORM和DAO提供了与第三方持久层框架的良好结合,简化底层数据库访问;

    6)Spring的高度开放,是开发者可以自己选用Spring框架的部分或者全部。

    3. Spring框架结构

    Spring框架包含大概20个模型,这些模型可以被分组为Core Container(Spring核心容器)、Data Access/Integration、Web、AOP、Instrumentation和Test,如上图显示。

    Core Container提供了框架的基本部件,包括IoC,即DI特性。

    IoC:控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心。 控制反转还有一个名字叫做依赖注入(Dependency Injection)。简称DI。

    IoC is named by Johnson and DI is named by Marine Fowler.

    不管是依赖注入还是控制反转,其含义完全相同:当某个Java实例(调用者)需要另一个Java实例(被调用这)时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。然而在依赖注入的模式下,创建被调用者的工作不再由调用者来完成,因此成为控制反转;创建被调用者实例的工作通常有Spring容器完成,然后注入调用者,所以称为依赖注入。

    举个例子:

    ①原始石器时代

    5112834c3da7f5ba0fb032a340ddda01

    在原始石器时代,需要工具的人只能去自己制造工具,对应Java程序中的情况为:调用者通过new关键字调用构造器创建一个被调用者。

    ②工业时代

    240369-1304300H14890

    在工业时代,社会有了分工,需要工具的仅仅需要购买工厂中生产的即可,对Java程序中的情况为:调用者通过简单工厂设计模式,只需定位工厂,无须管理被调用者的具体实现。也即面向接口编程。

    ③共产主义社会

    调用者“坐等”社会提供自己需要的被调用者即可。即等待Spring依赖注入。此时,实例之间的依赖关系有IoC容器负责管理。

    4. 两种依赖注入方式

    依赖入住通常有两种方式:

    ①投值注入:IoC容器使用属性的setter方法来注入被依赖的实例

    ②构造注入:IoC容器使用构造器来注入被依赖的实例。

    举例说明:

    public interface Person{
        //定义一个使用斧子的方法
        public void useAxe();
    }
    
    public interface Axe{
        //Axe接口里有个砍的方法
        public String chop();
    }
    
    //Spring推荐面向接口编程,这样可以更好的让规范和实现分离,从而提供更好的解耦。

    下面是Person类的实现

    public class Chinese implements Person
    {
        private Axe axe;
        //设值注入所需的setter方法
        public void setAxe(Axe axe)
        {
            this.axe = axe;
        }
        //实现Person接口的useAxe方法
        public void useAxe()
        {
            //调用axe的chop()方法,
            //表明Person对象依赖于axe对象
            System.out.println(axe.chop());
        }
    }

    上面的Chinese类并不知道它要调用的axe示例在哪里,也不知道axe实例是如何实现的,它是需要调用一个axe实例,这个axe实例将由Spring容器负责注入。

    下面是Axe的实现类:StoneAxe

    public class StoneAxe implements Axe
    {
        public String chop()
        {
            return "石斧砍柴好慢";
        }
    }

    当目前为止,程序依然不知道Chinese类和哪个Axe实例耦合,Spring当然也不知道,实际上,Spring需要使用XML配置文件来制定实例之间的依赖关系。

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Spring配置文件的根元素,使用spring-beans-3.0.xsd语义约束 -->
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <!-- 配置chinese实例,其实现类是Chinese -->
        <bean id="chinese" class="com.zf.service.impl.Chinese">
            <!-- 将stoneAxe注入给axe属性 -->
            <property name="axe" ref="stoneAxe"/>
        </bean>
        <!-- 配置stoneAxe实例,其实现类是StoneAxe -->
        <bean id="stoneAxe" class="com.zf.service.impl.StoneAxe"/>
    </beans>

    在配置文件,Spring配置Bean实例通常会制定两个属性:

    ①id:指定该Bean的唯一标识,程序通过id属性值来访问该Bean实例;

    ②class:指定该Bean的实现类,此处不可再用接口,必须使用实现类,Spring会使用XML解析器读取该属性值,并利用反射来创建该实现类的实例。

    下面是主程序,简单获取Person实例,并调用该实例的userAxe方法

    public class BeanTest
    {
        public static void main(String[] args)throws Exception
        {
            //创建Spring容器
            ApplicationContext ctx = new
                ClassPathXmlApplicationContext("bean.xml");
            //获取chinese 实例
            Person p = ctx.getBean("chinese" , Person.class);
            //调用useAxe()方法
            p.useAxe();
        }
    }

    上面程序的两行代码实现了创建Spring容器,并通过Spring实例来获取chinese实例。执行上面程序,就会看到控制台输出

    石斧砍柴好慢

    从上面的示例中可以看出,依赖注入以配置文件管理Bean实例之间的耦合,让Bean实例之间的耦合从代码层次分离出来。总结一句话:依赖注入是一种优秀的解耦方式。同时,我们还不难发现,Sping IoC容器的三个基本特点

    ①应用程序的各组件面向接口变成;

    ②应用程序的各组件不再由程序主动生产,而是由Sping容器来负责生产并初始化;

    ③Sping采用配置文件,或者Annotation来管理Bean的实现类、依赖关系;Spring容器则根据配置文件,利用反射来创建实例,并为之注入依赖关系。

    //-----------------------------2013-11-07 添加 -----------------------------------

    昨晚预习中提到的例子,是通过setter方法为目标Bean注入依赖关系的方式,即投值注入。下面用构造注入的方式,实现上面的例子。所谓的构造注入,在构造实例时就已经为其完成了依赖关系的初始化。

    对上面的Chinese类做简单的修改:

     public class Chinese implements Person{
         private Axe axe;
         //默认的构造器
         public Chinese(){
         }
         //构造注入所需的带参数的构造器
         public Chinese(Axe axe){
             this.axe = axe;
         }
         //实现Person接口的useAxe方法
         public void useAxe(){
             //调用axe的chop()方法
             //表明Person对象依赖于axe对象
             System.out.println(axe.chop());
         }
     }

    此时,并未为Chinese类的axe属性提供setter方法,而是通过一个带有axe参数的构造器,Spring为chniese注入所以来的Bean实例。

    构造注入的配置文件也需要进行适当的修改,为了使用构造注入,使用<constructor-arg.../>元素指定构造器的参数。修改之后的配置文件如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Spring配置文件的根元素,使用spring-beans-3.0.xsd语义约束 -->
    <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.springframework.org/schema/beans"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <!-- 配置chinese实例,其实现类是Chinese -->
        <bean id="chinese" class="com.zf.service.impl.Chinese">
            <!-- 使用构造注入,为chinese实例注入stoneAxe实例 -->
            <constructor-arg ref="stoneAxe"/>
        </bean>
        <!-- 配置stoneAxe实例,其实现类是StoneAxe -->
        <bean id="stoneAxe" class="com.zf.service.impl.StoneAxe"/>
    </beans>

    <constructor-arg.../>元素指定了一个构造器参数,该参数的类型是Axe,这指定Spring调用Chinese类里带有一个Axe参数的构造器来创建chinese实例,因为有参数的构造器创建实例,所以当Bean实例被创建完成之后,该Bean的依赖关系已经设置完成,这就是构造注入。

  • 相关阅读:
    BEM(Block–Element-Modifier)
    http://element.eleme.io/#/zh-CN/component/quickstart
    Commit message 的写法规范。本文介绍Angular 规范(
    好的commit应该长啥样 https://github.com/torvalds/linux/pull/17#issuecomment-5654674
    代码管理
    if you have content fetched asynchronously on pages where SEO is important, SSR might be necessary
    Martin Fowler’s Active Record design pattern.
    The Zen of Python
    Introspection in Python How to spy on your Python objects Guide to Python introspection
    Object-Oriented Metrics: LCOM 内聚性的度量
  • 原文地址:https://www.cnblogs.com/zifo/p/3411221.html
Copyright © 2011-2022 走看看