Spring-IoC中装配Bean

在Spring-IoC简介中简单介绍了什么是IoC以及一些相关的概念,这里将详细介绍如何通过IoC容器提供的方法进行注入和如何进行注入配置。

依赖注入

IoC提供的依赖注入方法主要有属性注入、构造函数注入和工厂方法注入,这里依次介绍如何通过各个方法注入Bean

属性注入

属性注入要求Bean提供一个默认的构造器,并为需要注入的属性提供对应的setter方法。Spring会检查Bean中是否有setter方法,但不会检查是否有对应的属性成员。
Bean的代码如下。

public class Car{
    private int maxSpeed;
    private String brand;
    //如果要通过属性注入则必须实现setter方法
    public void setXX( XX){
        this.XX=XX;
    }
}

我们这里通过XML文件对Bean进行设置,后面会详细介绍所有的配置方式和配置内容。


    200
    红旗CA72

这样设置完成后,当Spring启动后,就会自动生成idcarclassCar,属性分别为200红旗CA72Bean
对于属性的命名,要求变量的前两个字母要么全部大写,要么全部小写iCCardiDCode是非法的。如果取非法的变量名,在试图启动Spring时,将会失败。因此命名的建议是像QQ、MSN、ID等正常以大写字母出现的专业术语,在Java中一律使用小写形式

构造函数注入

当想要通过构造函数注入时,需要在Bean中实现相应的构造函数,并以想要注入的属性为参数。
Bean的代码如下。

public class Car{
    private int maxSpeed;
    private String brand;
    public Car(int maxSpeed,String brand){...};
}

然后我们在XML文件中进行配置。


  
        红旗
  
  
        200
  

在通过构造器注入时,配置文件中arg的顺序与构造器中的参数顺序无关,当只有一个构造器的情况下上述配置文件才会生效。因此建议使用索引匹配入参,即
当两个构造器仅有intdouble的区别(如下),则此时还需要在配置文件中加上参数类型以作区分,即

public class Car{
    private int maxSpeed;
    private double averageSpeed;
    private String brand;
    public Car(int maxSpeed,String brand){...};
    public Car(double averageSpeed,String brand){...};
}

如果构造函数的参数的类型是可以辨别的(非基础数据类型且入参类型各异),则可以不提供类型和索引的信息。
构造器注入可能会出现循环依赖的问题,即A类需要注入B类,B类需要注入A类,在这种情况下,使用属性注入就可以解决了。

工厂方法注入

在使用框架的过程中很少会使用到工厂方法注入,以下仅举2个例子。

  1. 非静态工厂类
public class CarFactory{
    public Car createHongQiCar(){}
}



由于工厂类不是静态的,因此需要先定义工厂类的bean。

  1. 静态工厂类
public class CarFactory{
    public static Car createHongQiCar(){}
}

Bean的配置方式

配置Bean可以通过XML、注解、Java类和Groovy DSL这四种方式,下面来详细介绍各个配置方法的细节。

基于XML的配置

对于基于XML的配置,Spring2.0以后采用Schema格式,使得配置文件更具扩展性,但文件头声明会复杂一些,下面是一个例子。



    
    

    
    
        
    

在上面的代码中定义了3个命名空间:

  1. xmlns="http://www.springframework.org/schema/beans",默认命名空间:没有空间名,用于Spring Bean的定义。
  2. xsi标准命名空间:这个命名空间用于指定自定义命名空间的Schema样式文件,是W3C定义的标准命名空间。
  3. xmlns:aop="http://www.springframework.org/schema/aop",aop命名空间:这个命名空间是Spring配置aop的命名空间,即一种自定义的命名空间。

命名空间的定义分为两个步骤:

  1. 第一步指定命名空间的名称,如xmlns:aop="http://www.springframework.org/schema/aop"aop为命名空间的别名,而"http://www.springframework.org/schema/aop"是命名空间的全限定名,习惯上用文档发布机构的官方网站和相关网站目录作为全限定名。如果命名空间的别名为空,则表示该命名空间为文档默认的命名空间。
  2. 第二步指定命名空间的Schema文档格式文件的位置,用空格或回车换行进行分隔。定义的语法如下<命名空间1> <命名空间1Schema文件> <命名空间2> <命名空间2Schema文件>(注意之间的分隔符可以为空格或换行符)。Schema地址有2个用途:一是XML解析器可以获取Schema文件并对文档进行格式合法性验证;二是IDE可以引用Schema文件对文档编辑提供自动补全功能。

以上就是一个XML配置文件的结构介绍,接下来将介绍如何对Bean进行定制。

  • 字面值
    对于基本类型或其封装类,我们在XML中可以直接进行设置。对于字符串来说,如果其中包含了&、<、>、"、'这5种特殊字符,可以通过下面的![CDATA[]]进行包装,使得XML解析器将其中的内容当成纯文本;或者可以通过转义序列来表示&、<、>、"、&apos。
    
     
         200
     
     
         
     
    
    
  • 引用其他bean
    可以通过以下3种标签对其他的bean进行引用。
    1. bean:可以引用同一容器或父容器总的Bean,这是最常见的形式。
    2. local:只引用同一配置文件中的Bean。
    3. parent:只引用父容器中的Bean。
    
    
    
      
        
      
    
    
    
    
    
    
    
    
      
    
    
  • 内部bean
    我们也可以通过隐藏类那样定义bean。
    
      
        
          
        
      
    
    
  • null值
    如果想要注入null值,需要显示的将值设为,即
  • 级联属性
    
      
    
    
    如果想要通过这种方式直接对boss中的car的属性进行设置,则需要在Boss类中声明一个初始化对象并实现getter()方法。
    public class Boss{
      private Car car=new Car();
      public Car getCar(){return car;}
    }
    
  • 集合类
    1. List
    
      
        
          看报
          滑雪
        
      
    
    
    如果List的属性类型可以通过字符串字面值进行配置,那么就可以使用这种方式,如String[]int[]等。
    此外,List还可以通过注入容器中其他的Bean。
    1. Set
    
      
        
          看报
          滑雪
        
      
    
    
    1. Map
    
      
        
          
            AM
            会见客户
          
          
            PM
            开会
          
          
          
            
            
          
        
      
    
    
  • Properties
    Properties属性可以看成键值都是字符串的Map类型。
    
      
        
          [email protected]
        
      
    
    
  • 强类型集合
    Spring配置强类型和非强类型集合相同,会将值自动转换为目标类型。
    public class Car{
      private Map passengers=new HashMap();
    }
    
  • 集合合并
    
     
       
         看报
       
     
    
    
     
        
         看报
       
     
    
    
  • 配置集合类型的Bean
    如果想要配置集合类型的Bean,而不是属性类型的集合,可以通过在Spring配置文件中引入util命名空间的声明,然后进行配置。
    
         xsi:shcemaLocation="http://www.springframework.org/schema/util
                                            http://www.springframework.org/schema/util/spring-util-4.0.xsd"
     
       喝茶
       看报
     
    
    
简化XML配置方式
  1. 字面值属性
类型 简化前 简化后
字面值属性 200
构造函数参数 200
集合元素

AM
见客户



  1. 引用对象属性
类型 简化前 简化后
字面属性值
构造函数
集合元素


的简化形式对应于,而没有对应的简化形式。

  1. 使用p命名空间

  
  

基于注解的配置

采用基于注解的配置文件,则Bean定义信息通过在Bean实现类上标注注解实现。

//这里定义了一个Dao的Bean
/*
  与@Component功能相似的还有:
    @Repository:用于对DAO实现类进行标注
    @Service:用于对Service实现类进行标注
    @Controller:用于对Controller实现类进行标注
*/
@Component("carDao")    
public class CarDao{
  //..
}

对于通过注解定义的bean需要在Spring配置文件中进行额外设置。


  
  
  

Bean完成配置后,还需要通过注解进行自动注入

@Service
public class LoginService{
  //注入LogDao的bean
  //对required=false设置,当Spring启动时如果未找到对应的bean则不会报错
  //通过Qualifier可以指定对应bean的名称
  @Autowired(required=false)
  @Qualifier("logDao")
  private LogDao logDao;
  
  //对类方法进行标注
  @Autowired
  @Qualifier("logDao")
  public void setLogDao(LogDao logDao){}
  //或者通过这种形式
  public void setLogDao(@Qualifier("logDao")LogDao logDao){}

  //如果对类中集合类的变量或方法入参进行标注,那么Spring会将容器中类型匹配的所有Bean都注入
  @Autowired
  private List plugins;
  //Spring如果发现变量是一个list和一个map,会将容器中匹配集合元素类型的所有bean都注入
  //这里将会把plugins的bean注入map集合,key是bean的名字,value是所有实现了plugin的bean。
  @Autowired
  private Map pluginMaps;
  //如果Plugin有多个实现类,那么可以在不同的实现类前用@Order(value=1)对注入顺序进行设置,越小越先加载
}

基于Java类的配置、基于Groovy DSL的配置

一般来说,使用XML和标注的方式就能解决几乎所有的任务。建议使用XML配置DataSource、SessionFactory等资源bean,在XML中利用aop、context命名空间进行相关主题的配置,其余所有项目中开发的Bean都通过基于注解配置的方式进行配置。

Bean基本配置

Bean的命名

Bean的id属性命名与Java变量的命名要求相同,而name属性命名没有任何字符上的限制。可以通过不设置id属性命名来实例化匿名Bean




这样就实例化了3个匿名Bean,第一个Bean通过getBean("Car")获得,第二个通过getBean("Car#1")获得。

依赖注入

Spring支持属性注入和构造函数注入,除此之外还支持工厂法注入方式。

你可能感兴趣的:(Spring-IoC中装配Bean)