五 Spring-IoC XML配置

目录

1. Web MVC发展史历程
2.Spring概要
3.Spring-依赖注入概要(IOC)
4.属性注入的三种实现方式
5.Spring-IoC XML装配
6.Spring-XML设置Bean的值
7.Spring-IoC 注解(1)
8.Spring-IoC 注解(2)
9.Spring-AOP切面编程(1)
10.Spring-AOP切面编程(2)
未完待续...

Spring-IOC配置

一、概要

1、简介

Spring支持三种方式配置Bean,Spring1.0仅支持基于XML的配置,Spring2.0新增基于注解配置的支持,Spring3.0新增基于Java类配置的支持,Spring4.0则新增给予Groovy动态语言配置的支持。

  1. Explicit configuration in XML:显示的XML配置
  2. Explicit configuration in Java:显示的JavaConfig,基于java类配置
  3. Implicit bean discovery and automatic wiring:隐式的bean扫描,基于java注解配置,自动注入
  4. Explicit configuration in Groovy DSL:Groovy动态语言配置

在实际开发中前面三种方式都会用到,后面一种相对用的比较少,因为需要学习Groovy语言

2、使用原则

  1. 隐式的bean扫描,基于注解自动注入(优先使用)
    优点:在class文件中,降低维护成本。不需要第三方解析工具,利用java反射机制。编辑期就可以检验正确性,提高开发效率。
    缺点:如果需要对注解进行修改,那么要重新编译整个工程。Bean之间的关系不好把控。符合条件的多个Bean注入时会抛出异常
  2. Java 接口和类中配置实现配置(没办使用注解可以采用此方式)
    同隐式的bean扫描,基于注解
  3. XML配置(第三方框架,无法修改源代码的情况下)
    优点:简单易懂,配置文件修改不需要重新编译,扩展起来相对容易,比较典型的应用场景就是第三方的库中,一般都采用此种配置方式
    缺点:配置文件过多的时候难以管理

二、XML配置

1、说明

使用 XML 装配 Bean 需要定义对应的 XML,这里需要引入对应的 XML 模式(XSD)文件,这些文件会定义配置 Spring Bean 的一些元素,当我们在 IDEA 中创建 XML 文件时,会有友好的提示

2、前期准备工作

  1. 在pom.xml文件中添加
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.1.4.RELEASE</version>
    </dependency>
    
  2. 创建xml文件


    image

四、beans配置

1、命名空间(xmlns)

  1. 说明
    这一功能是在spring2之后引进来的,spring的容器启动时回去寻找jar包下面的META-INF,看里面是否有spring.schema或者是spring.handlers,这个handler文件里面就定义了命名空间以及处理这个命名空间的Java类
  2. 完整结构图


    image
  3. 说明
    • beans(常用)
      支持声明Bean和装配Bean,是Spring最核心也是最原始的命名空间
    • context(常用)
      为配置Spring应用上下文提供配置元素,包括自动检测和自动装配、注入非Spring直接管理的对象
    • aop(常用)
      为声明切面以及@AspectJ注解切面提供配置元素
    • tx(常用)
      提供声明式事务配置
    • util(常用)
      提供各种各样的工具类,包括集合配置为Bean、支持属性占位符元素
    • mvc(常用)
      启用Spring MVC能力,例如面向注解的控制器、视图控制和拦截器

2、XML配置的结构

  1. 简单的结构
    <beans>
        <bean id="" class="">
          <property name="" value=""/>
        </bean>
        <alias alias="alias" name="alias" />
        <import resource="xxx.xml" />
    </beans>
    
  2. 说明
    • <bean>标签
      主要用来进行Bean定义
    • <alias>标签
      用于定义Bean别名
    • import标签
      用于导入其他配置文件的Bean定义,这是为了加载多个配置文件,当然也可以把这些配置文件构造为一个数组(new String[] {“xxx.xml”, xxx.xml})传给ApplicationContext实现进行加载多个配置文件,那一个更适合由用户决定;这两种方式都是通过调用Bean Definition Reader 读取Bean定义,内部实现没有任何区别。<import>标签可以放在<beans>下的任何位置,没有顺序关系

五、bean的xml装配

1、说明

在spring容器内拼凑bean叫作装配。装配bean的时候,你是在告诉容器,需要哪些bean,以及容器如何使用依赖注入将它们配合在一起

2、Bean配置

  1. 完整的配置文件
    <!--配置bean,配置后该类由spring管理--> 
    <bean class="这个Bean的类"  
          name/id="Bean在容器里面的唯一名称" 
          scope="Bean的作用域范围"  
          autowiring-mode="这个Bean的properties的自动注入方式"  
          lazy-init="是否为懒加载"
          init-method="容器初始化该Bean后的回调方法"  
          destroy-method = "容器在销毁该Bean后的回调方法"    
          abstract="是否为抽象Bean,主要用来统一XML配置文档里面的很多Bean的属性配置,与Java的Abstract Class无任何关系"
          parent="父Bean的名称,会继承父Bean的属性,也是只在配置文档中有效,与Java的Class无任何关系"
          factory-method="工厂方法的名字"
          factory-bean="工厂Bean的名字"
          depends-on ="依赖Bean的名字,Spring保证会在初始化这个Bean前先初始化被依赖的Beans,这个属性不会被子Bean继承,子Bean要重新写自己的depends-on"      
          autowire-candidate = "是否为自动注入的候选,一般当其他Bean设置autowiring-mode属性为自动搜寻时可以避免或允许该Bean被列入匹配列表"    
          primary = "是否将该Bean在其他Bean的自动注入候选人中设为首选">  
        <!-- Constructor-arg方式给属性赋值写法一 -->
        <constructor-arg type="int" value="1"/>
        <!-- Constructor-arg方式给属性赋值写法二-->
        <constructor-arg name="xx" value="2"/>
        <!-- Constructor-arg方式给属性赋值写法三-->
        <constructor-arg index="0" value="3"/>
        <!-- Properties方式给属性赋值写法一-->
        <property name="xx">
            <ref bean="另外一个Bean的名字"/>
        </property>
        <!-- Properties方式给属性赋值写法二-->
        <property name="xx" ref="另外一个Bean的名字"/>
        <!-- Properties方式给属性赋值写法三-->
        <property name="integerProperty" value="1"/>       
    </bean>
    

六、bean配置说明

1、id(常用)

  1. 说明
    • Bean 的名称,在 IOC 容器中必须是唯一的 , 代码中通过BeanFactory获取JavaBean实例时需以此作为索引名称
    • 命名必须以字母开头,可以使用字母、数字、连字符、下划线、句号、冒号、 /*
    • 若id没有指定,Spring 自动将全限定名#{number}作为 Bean 的名字,com.wener.example.bean.User#0
    • id 可以指定多个名字,名字之间可用逗号、分号、或空格分隔
  2. 示例代码
    // java 代码
    public class User {
        private String name;
        private  String password;
    }    
    
    <!-- xml配置 -->
     <bean id="user,userId" class="com.wener.example.bean.User"/>
    

2、name(了解)

  1. 说明
    同上,如果给bean增加别名,可以通过name属性指定一个或多个。以废弃,用id代替

3、class(常用)

  1. 说明
    一个类的全限定名(类的完整路径)
  2. 示例代码
    <!-- xml配置 -->
     <bean class="com.wener.example.bean.User"/>
    

4、scope(常用)

  1. 说明
    用来配置 spring bean 的作用域。在spring2.0之前bean只有2种作用域即:singleton(单例)、non-singleton(也称 prototype), Spring2.0以后,增加了session、request、global session三种专用于Web应用程序上下文的Bean。因此,默认情况下Spring2.0现在有五种类型的Bean。当然,Spring2.0对 Bean的类型的设计进行了重构,并设计出灵活的Bean类型支持,理论上可以有无数多种类型的Bean,用户可以根据自己的需要,增加新的Bean类 型,满足实际应用需求
  2. 可选值
    类型 说明
    singleton 默认值,在Spring IoC容器中仅存在一个Bean实例,Bean以单实例的方式存在
    prototype 每次从容器中调用Bean时,都返回一个新的实例
    request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
    session 同一个HTTP session共享一个Bean,不同的HTTP session使用不同的Bean,该作用域仅适用于WebApplicationContext环境
    globalSession 同一个全局Session共享一个Bean,一般用于Portlet环境,该作用域仅适用于WebApplicationContext环境
  3. singleton(单例)
    • 说明
      当一个bean的 作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把 一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,并且所有针对该bean的后续请求和引用都 将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中 只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean,如果不希望在容器启动时提前实例化singleton的Bean,可以使用lazy-init属性进行控制
    • 示例代码
      <bean id="user" class="com.wener.example.bean.User" scope="singleton"/>
      // 或者
      <bean id="user" class="com.wener.example.bean.User" singleton="true"/>
      
      private static void test() {
          ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
          UserDao dao = context.getBean("userDao", UserDao.class);
          UserDao dao1 = (UserDao) context.getBean("userDao");
          System.out.println(dao);
          System.out.println(dao1);
      }
      // 两次输入的内存地址一致,说明是同一个对象
      // com.wener.example.dao.impl.UserDaoImpl@46fa7c39
      // com.wener.example.dao.impl.UserDaoImpl@46fa7c39
      
  4. prototype
    • 说明
      设置为scope=”prototype”之后,每次调用getBean()都会返回一个新的实例
      默认情况下,容器在启动时不会实例化prototype的Bean
      Spring容器将prototype的Bean交给调用者后就不再管理它的生命周期
    • 示例代码
      <bean id="user"
            class="com.wener.example.bean.User"
            scope="prototype">
      
      ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
      User user = context.getBean("user", User.class);
      User user1 = context.getBean("user",User.class);
      System.out.println(user);
      System.out.println(user1);
      // 两次输入的内存地址不一样
      // com.wener.example.bean.User@46fa7c39
      // com.wener.example.bean.User@1fb700ee
      
  5. request
    • 说明
      request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,配置实例:request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置:如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可:
    • 示例代码
      <web-app>
         ...
        <listener>
      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
        </listener>
         ...
      </web-app>
      
      <bean id="user"
                class="com.wener.example.bean.User"
                scope="request"
                init-method="init"
                destroy-method="destroy">
      </bean>
      
  6. session
    • 说明
      session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效,和request配置实例的前提一样,配置好web启动文件就可以如下配置
    • 示例代码
      <web-app>
         ...
        <listener>
      <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
        </listener>
         ...
      </web-app>
      <bean id="user"
                class="com.wener.example.bean.User"
                scope="session"
                init-method="init"
                destroy-method="destroy">
      </bean>
      

5、abstract

  • 说明
    设定ApplicationContext是否对bean进行预先的初始化。
  • 可选值
    默认false默认不预先初始化,true预先初始化
    • 示例代码
        <bean id="user"
                class="com.wener.example.bean.User"
                abstract="true"
                scope="session"
                init-method="init"
                destroy-method="destroy">
          </bean>
      

6、parent

  1. 说明
    通过设置标签的parent属性,子将自动继承父的配置信息
  2. 可选值
    父类id的值
  3. 示例代码
    public class Parent {
        private String name;
        ...
    }
    public class Child extends Parent {
        private int age;
     ...
    }
    
    <bean id="parent"
        class="com.wener.example.bean.Parent">
            <property name="name" value="小明"/>
        </bean>
    <bean id="child"
         parent="parent"
         class="com.wener.example.bean.Child">
         <property name="age" value="10"/>
    </bean>
    

8、init-method

  1. 说明
    初始化方法,此方法将在BeanFactory创建JavaBean实例之后,在向应用层返回引用之前执行。一般用于一些资源的初始化工作。
  2. 示例代码
    # java
    public class User implements Serializable {
        public void init() {
            System.out.println("初始化");
        }
    }   
    // xml配置
    <bean class="com.werner.di.User" 
          name="user"
          init-method="init"/>
    

9、destroy-method

  1. 说明:
    销毁方法,此方法将在BeanFactory销毁的时候执行,一般用于资源释放。
  2. 示例代码
    public class User implements Serializable {
        public void destroy() {
        }
    }
    
    <bean class="com.wener.example.bean.User" 
          id="user"
            init-method="init" destroy-method="destroy"/>
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容