zoukankan      html  css  js  c++  java
  • 基础篇——Spring之IOC容器装配Bean

    1、Spring装配Bean的过程大致如下:

        Spring启动时读取应用程序提供的bean配置信息,并在Spring容器中生成一份该Bean的配置信息注册表,再根据该注册表实例化Bean,装配Bean的属性信息,Bean之间的依赖关系和Bean的行为配置。需要满足的三个条件:Spring框架的相关jar包(Spring容器)、Bean的配置信息、Bean的实现类。

    2、bean配置信息的装载方式:XML的配置方式,基于注解的配置方式,基于Java类的配置方式,Groovy动态语言的配置方式。

    3、XML配置方式之Schema配置大致包含两部分:一部分需要对用到的命名空间进行声明;另一部分则需要对声明的命名空间进行定义,定义包括命名空间名称和位置。

        命名空间的声明:通过xmlns:别名=“命名空间名称”的格式,如下:

    //默认命名空间的声明
    xmlns="http://www.springframework.org/schema/beans"
    //标准命名空间的声明
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    //aop命名空间的声明
    xmlns:aop="http://www.springframework.org/schema/aop"

         注:默认命名空间没有别名,常用标签<beans></beans>,<bean></bean>

         注:aop是自定义命名空间,常用标签<aop:config></aop:config>

        命名空间的定义:通过xsi:schemaLocation=“命名空间全称   schema文件位置”的格式,如下:

    xsi:schemaLocation=
            "http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
             http://www.springframework.org/schema/aop
             http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"

     4、XML配置方式之Spring常用的Schema文件:

        spring-beans-4.0.xsd:用于配置Bean;  spring-aop-4.0.xsd:用于AOP的配置;  spring-tx-4.0.xsd:用于声明式事务的配置;  spring-mvc-4.0.xsd:用于MVC的配置;  spring-util-4.0.xsd:用于简化某些标准配置;  spring-jee-4.0.xsd:用于简化JavaEE中EJB、JNDI等功能的配置;  spring-jdbc-4.0.xsd:用于Spring内嵌数据库的配置;  spring-jms-4.0.xsd:用于JMS的配置;  spring-lang-4.0.xsd:用于集成Groovy等动态语言;  spring-oxm-4.0.xsd:用于对象XML映射的配置;  spring-task-4.0.xsd:用于任务调度;  spring-tool-4.0.xsd:用于集成一些工具。

     5、XML配置方式之装配Bean,如下:

    <beans  xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation=
         "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id="car" class="com.smart.simple.Car"/> <bean name="boss" class="com.smart.simple.Boss"/> </beans>

         注:bean的命名可以用id或name,其中id被要求必须以字母开头且不能出现逗号、空格等非结束符号,name没有字符限制。

         注:bean可以指定多个名称,如下:

    <bean id="car,car1,car2" calss="com.smart.simple.Car"/>
    <bean name="boss1,boss2,boss3" calss="com.smart.simple.Boss">

     6、XML配置方式之属性注入,大致有三种注入方式:第一种属性注入,第二种构造函数注入,第三种工厂方法注入。

        属性注入是通过该属性的setter方法进行注入的方式,一般需要两个条件:一个是需要被注入对象有空参数的构造函数,另一个是需要被注入对象有该属性的setter方法设置值。Spring容器先调用空构造实例化被注入的bean,再调用其setter方法注入属性值,被注入对象示例如下:

    package com.smart.ditype
    public class Car{
        
        private String color;
        //被注入对象的空构造
        public Car(){}
        //被注入对象属性的setter方法
        public void setColor(String color){
            
            this.color = color;
      }
    }

         注:如果类中没有定义任何构造函数,那么JVM会自动生成一个默认的空构造,上述Bean的配置文件如下:

    <bean id="car" class="com.smart.ditype.Car">
        <property name="color" value="红色">
    </bean>

    7、XML配置方式之构造函数注入:

        构造函数注入是Bean在实例化时以参数的形式注入,大致有三种入参方式:根据类型入参、根据索引入参、类型和索引的联合、通过自身类型的反射入参。被注入对象的有参构造函数如下:

    package com.smart.ditype
    public class Car{

    private String color;

    private int maxSpeed; //被注入对象的有参构造
    public Car(String color,int maxSpeed){

    this.color = color;

    this.maxSpeed = maxSpeed;
    } }

        该对象Bean的配置文件如下:

    <bean id="Car" class="com.smart.ditype.Car">
        <constructor-arg type="java.lang.String">
            <value>红色</value>
        </constructor-arg>
        <constructor-arg type="java.lang.Integer">
            <value>200</value>
         </constructor-arg>
    </bean>

        注:在被注入对象的有参构造函数里,参数类型各不相同时,采用类型入参。若是有多个相同类型的参数,一般采取根据索引入参,其有参构造函数如下:

    package com.smart.ditype
    public class Car{

    private String color;

    private String type;
    //被注入对象的有参构造 public Car(String color,String type){

    this.color = color;

    this.type = type;
    } }
     

        该对象Bean的配置文件如下:

    <bean id="car" class="com.smart.ditype.Car">
        <constructor-arg index="0" value="红色"/>
        <constructor-arg index="1" value="X-LL130"/>
    </bean>

         注:在属性注入中Spring会通过属性名找到Bean对象中的setter方法设置属性,而在构造函数注入中Spring不能通过属性名找到构造函数的参数,需要通过类型或索引间接设置参数。若是重载多个参数个数相同的构造函数,被注入对象如下:

    package com.smart.ditype
    public Car{
    
        private String color;
    
        private String type;

    private double price;
    private int maxSpeed; //被注入对象的有参构造 public Car(String color,String type,int maxSpeed){ this.color = color;

    this.type = type;
    this.maxSpeed = maxSpeed; } //重载有参构造 public Car(String color,String type,double price){
    this.color = color;
    this.type = type; this.price = price; } }

        注:上述使用索引入参不能准确的注入到需要的构造函数中,需要在Bean对象的配置文件中联合使用类型入参和索引入参,如下:

    <bean id="car" class="com.smart.ditype.Car">
        <constructor-arg index="0" value="红色"/>
        <constructor-arg index="1" value="x-ll123"/>
        <constructor-arg index="3" type="java.lang.Integer" value="200"/>
    </bean>

        注:这样就能准确的将属性值注入到被注入对象的第一个有参构造中。但是使用有参构造函数注入方式可能出现循环依赖的问题,如下:

    package com.smart.ditype
    public class Car{
        
        private Boss boss;
        //被注入对象注入Bean
        public Car(Boss boss){
    
            this.boss = boss;
        }
    }
    package com.smart.ditype
    public class Boss{
        
        private Car car;
        //被注入对象注入Bean
        public Boss(Car car){
        
            this.car = car;
        }
    }

        bean的配置文件如下:

    <bean id="car" class="com.smart.ditype.Car">
        <constructor-arg index="0" ref="boss"/>
    </bean>
    <bean id="boss" class="com.smart.ditype.Boss">
        <constructor-arg index="0" ref="car"/>
    </bean>

        注:Spring容器通过构造函数实例化Bean,前提是Bean构造函数引入的参数必须是准备就绪的。当①对象需要注入一个Bean,注入方式采用的是构造函数注入,而这个Bean需要注入①对象,注入方式也采用的是构造函数注入,那么这两个bean都不能通过Spring容器进行实例化,这个问题就是循环依赖,类似于线程死锁的循环。

     

  • 相关阅读:
    c/c++面试45-50之字符串
    c/c++面试39-44之内存动态分配
    使用spring配合Junit进行单元测试的总结
    使用springBoot进行快速开发
    配置项目使用weblogic的JNDI数据源
    转载-解决使用httpClient 4.3.x登陆 https时的证书报错问题
    SpringData JPA查询分页demo
    Lucene中的域选项
    代码片段,lucene基本操作(基于lucene4.10.2)
    配置maven使用nexus
  • 原文地址:https://www.cnblogs.com/zzb-yp/p/9957420.html
Copyright © 2011-2022 走看看