简析spring框架中Bean的配置和注入

1.1.基于xml配置Bean

基于xml配置bean时,spring通过配置来实例化、设置bean的属性以及设置bean之间的相互依赖。
一个通常需要定义id和class属性。class属性是必须的,不然spring框架不知道是那个,id不是必要的,如果配置文件中配置的其他bean引用这个bean的话,那么id也是必要的,通常情况下都是加上的。

<bean id="DirthAir" class="com.gaolei.ioc.DirtyAir">
             <qualifier value="dirthair"></qualifier>
         </bean>

1.2使用注解定义Bean

如果采用xml配置,bean定义信息和bean实现类本身是分离的,而采用基于注解的配置方法时,bean定义信息就通过在bean实现类上标注注解实现。

@Component
public class DirtyAir implements IAir {
    @Override
    public String toString() {
        return "DirtyAir";
    }
}

使用@Component注解在DirtyAir类声明处进行标注,这样就可以自动的被spring容器所识别了,自动将POJO转化为spring容器管理的一个bean。和是一样的效果。
spring提供了以下几个和@Component等效的注解,

  • @Repository:用于DAO实现类进行标注。
  • @Service: 用于对Service实现类进行标注
  • @Controller:用于对Controller实现类进行标注

1.3基于java类提供Bean定义

在普通的pojo类中只要标注@Configuration注解,就可以为spring容器提供bean定义信息,每个标注@Bean的类方法都相当于提供了一个bean的定义信息(省去了xml配置多个bean的烦恼了)

@Configuration
public class AppConf {
    @Bean
    public CleanAir cleanAir(){
        return new CleanAir();
    }

    @Bean
    public DirtyAir dirtyAir(){
        return new DirtyAir();
    }

    @Bean
    public Person person(){
        return new Person(dirtyAir());
    }
}

我们只需要在xml中配置开启context扫描就 可以实现bean的配置。

 <bean id="conf" class="com.gaolei.entity.AppConf"></bean>

==============================================================
部分代码(有的注解和xml是重复了,本次只是写作案例,重复了我自己也就懒的改了):

在这里插入图片描述

@Component
public interface IAir {
}
@Component
public class CleanAir implements IAir{
    @Override
    public String toString() {
        return "CleanAir";
    }
}
@Component
public class DirtyAir implements IAir {
    @Override
    public String toString() {
        return "DirtyAir";
    }
}
public class Person {

    @Autowired
    public Person(@Qualifier("dirthair") IAir iAir) {
        this.iAir = iAir;
    }

    IAir iAir;

    public void Breath(){
        System.out.println(this.iAir.toString());
    }
}
@Configuration
public class AppConf {
    @Bean
    public CleanAir cleanAir(){
        return new CleanAir();
    }

    @Bean
    public DirtyAir dirtyAir(){
        return new DirtyAir();
    }

    @Bean
    public Person person(){
        return new Person(dirtyAir());
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
        ">
       <context:component-scan base-package="com.gaolei.ioc"/>
        <!-- <bean id="CleanAir" class="com.gaolei.ioc.CleanAir">
             <qualifier value="cleanair"></qualifier>
         </bean>
         <bean id="DirthAir" class="com.gaolei.ioc.DirtyAir">
             <qualifier value="dirthair"></qualifier>
         </bean>
         <bean id="Person" class="com.gaolei.ioc.Person">
         </bean>-->
    <bean id="conf" class="com.gaolei.entity.AppConf"></bean>
</beans>

Bean的注入

2.1XML方式注入

2.1.1属性注入:

在我们之前实例化一个对象的时候,我们都是通过new xxx来实现的,然后通过set()方法设置对象的属性值,现在spring框架也是这样操作的,只不过是在框架内部完成。spring容器会先调用bean的默认构造器实例化bean对象(默认的都是无参构造器),然后通过反射的方式调用setter()方法注入属性值。

public class XMLInstance {
    private String name;
    private IAir iAir;

    public void setName(String name) {
        this.name = name;
    }

    public void setiAir(IAir iAir) {
        this.iAir = iAir;
    }

    public void Breath(){
        System.out.println("Name:"+ this.name+"iAir:"+this.iAir.toString());
    }
}
 <!--属性注入  property配置属性  name:属性名字-->
         <bean id="xmlinstance" class="com.gaolei.ioc.XMLInstance">
             <property name="iAir" ref="cleanAir"></property>
             <property name="name" value="hufan"></property>
          </bean>

2.1.2构造函数注入:

在属性注入时会先使用默认的构造函数实例化,然后通过set方法注入属性,在传统实例化对象时可以自定义构造函数进行实例化,构造函数注入就是通过自定义构造函数来进行对象的实例化,现在对上面XMLInstance类做一点点改变。

public class XMLInstance {
    private String name;
    private IAir iAir;

    public XMLInstance(String name, IAir iAir) {
        this.name = name;
        this.iAir = iAir;
    }



    public void Breath(){
        System.out.println("Name:"+ this.name+"iAir:"+this.iAir.toString());
    }
}
<bean id="xmlcontru" class="com.gaolei.ioc.XMLInstance">
        <constructor-arg index="1" ref="cleanAir"></constructor-arg>
        <constructor-arg index="0" value="hufan"></constructor-arg>
    </bean>

2.2注解方式注入

2.2.1常用注解介绍

  1. @Autowired:默认按类型匹配注入bean,可以对类成员变量,方法以及构造函数进行标注,完成自动装配工作。在使用该注解的时候,首先会在容器中查询对应类型的bean,如果查询的结果为一个,就将bean装配给@Autowired指定的数据,如果不止一个的话,那么@Autowired会根据名称查找,如果查询结果为空,那么会抛出异常,解决方法时,使用requied=false
  2. @Qualifier:@Autowired默认是单例的,但是面向接口编程中,如果把一个属性设置为接口类型,一个接口有多个实现类,那么到底注入哪一个了,为了解决这个问题就用到了该注解,比如上面写的代码中就用到了这个注解@Autowired
    public Person(@Qualifier(“dirthair”) IAir iAir) {
    this.iAir = iAir;
    }
    3.@Resource:默认按名称匹配注入bean。要求提供一个bean名称的属性(就是这个属性是一个bean的名字),如果属性为空,就自动采用标注处变量名或者方法作为bean的名称,如果我们没有在使用@Resource时指定bean的名称,同时spring容器中又没有该名字的bean,这是@Resource就自动退化为@Autowired,按照类型注入。
    4.@Value:在xml配置属性时候可以通过property的value设置默认值,@Value也可以为属性设置默认值。
public class AnnoIntance {
    @Value("gaolei")
    private String name;

    private IAir air;


    public void setName(String name) {
        this.name = name;
    }

    @Resource(name = "CleanAir")
    public void setAir(IAir air) {
        this.air = air;
    }

    public void Breath(){
        System.out.println("Name:"+ this.name+"iAir:"+this.air.toString());
    }
}

开启注解后才生效:

<context:annotation-config/>

版权声明:本文为weixin_43481793原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。