• 装配Bean


    spring提供了三种bean的装配机制

    • 一、在XML中进行显示配置;
    • 二、在Java中进行显示配置;
    • 三、隐式的bean发现机制和自动装配

    一、自动化装配bean

    CD播放器依赖于CD,只有将CD插入(注入)到CD播放器,CD播放器才能放出音乐。

    1、spring从两个角度来实现自动化装配

    • 组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean
    • 自动装配(autowiring):spring自动满足bean之间的依赖

    2、@Component 注解表明该类会作为组件类,并告知spring要为这个类创建bean;组件扫描默认不启用,需组合@ComponentScan 注解使用。

    3、@ComponentScan 启用组件扫描,如果没有其他配置,@ComponentScan默认会扫描与配置类相同的包。例,CDPlayerConfig类位于soundsystem包中,因此spring将会扫描这个包及这个包下的所有子包,查找带有@Compnent注解的类,这样就能发现CompactDisc,并且会在spring中自动为其创建一个bean;在xml中的使用:<context:componet-scan base-package="com.spring.soundsystem">。

    4、为组件扫描的bean命名:spring应用上下文中所有的bean都会给定一个ID,@Component注解默认为ID为类名首字母小写,可自定义命名@Component("newName");也可以使用Java依赖注入规范中提供的@Named注解为bean设置ID,如:@Named("newName")。大多数场景中两者可相互替换,但推荐使用@Component,因为@Named注解语意不明。

    5、设置组件扫描的基础包

    @componetScan会以配置类所在的包作为基础包(base package)来扫描组件,如果我们将配置类放在单独的包中,使其与其他的代码区分开来,就需要在@Component的value属性中指明包的名称:

    @Configuration
    @ComponentScan("com.spring.soundsystem")
    public class CDPlayConfig{
    }
    

      如果想更加清晰的表明设置的基础包,可以通过basePackage属性进行配置:

    @Configuration
    @ComponentScan(basePackages="com.spring.soundsystem")
    //@ComponentScan(basePackages{"com.spring.soundsystem","com.spring.video"})
    public class CDPlayConfig{
    }
    

      以上方法基础包为String类型,这种方法是类型不安全的(not type-safe),@Componet还提供另外一种方法,那就是将其指定为包中所包含的类或者接口

    @Configuration
    @compnentScan(basePackageClasses={CDPlayer,class,Video.claass})
    public class CDPlayerConfig{
    }
    

      6、通过为bean添加注解实现自动装配

      @autowired注解可用在类的任何方法上,不仅能够用在构造器上,还能用在属性的Setter方法上;如果没有匹配的bean,那么在应用上下文创建的时候,spring会抛出一个异常,为避免异常,可将@autowired的required属性设置为false,即:@autowired(required=false);将required属性设置为false时,spring会尝试执行自动装配,如果没有匹配的bean,sping将会让这个bean处于为装配的状态。同时,需要先在代码中进行null检查,否则会出现NullPointerException。如果有多个bean都能满足依赖关系,spring会抛出一个异常,表明没有明确指定选择哪个bean进行自动装配。可使用Java依赖注入规范的@Inject注解替换@Autowired。

    二、通过Java代码装配bean(JavaConfig)

    1、创建JavaConfig类的关键在于为其添加@Configruration注解,@Configuration注解表明这个类是一个配置类,该类应包含在spring应用上下文中如何创建bean的细节。

    2、声明简单的bean

    // @Bean注解会告诉spring这个方法返回一个对象,该对象要注册为spring应用上下文的bean
    // 默认情况下,bean的id与带有@Bean注解的方法名是一样的
    // 如果想设置一个不同的名字,可以重命名该方法,也可以通过name属性指定一个不同的名字,@Bean(name = "lonelyHeartsClubBand")
    @Bean
    public CompactDisc sgtPeppers(){
      return new SgtPeppers();    
    }
    

    3、借助JavaConfig实现注入

    在JavaConfig中装配bean的最简单方式就是引用创建的bean的方法。

    // 看起来CompactDisc是通过调用sgtPeppers()得到的,但情况并非完全如此。因为sgtPeppers()方法上添加了@Bean注解,spring将会拦截所有对它的调用,并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用
    @Bean
    public CDPlayer cdPlayer(){
      return new CDPlayer(sgtPeppers()) ;
    }
    // 另一种理解起来更为简单的方式,CDPlayer的构造器实现DI
    @Bean
    pubic CDPlayer cdPlayer(CompactDisc compactDisc){
        return new CDPlayer(compactDisc);
    }
    // Setter方法注入
    public CDPlayer cdPlayer(CompactDisc compactDisc){
        CDPlayer cdPlayer = new CDPlayer(compactDisc);
        cdPlayer.setCompactDisc(compactDisc);
        return cdPlayer;
    }
    

    三、通过XML装配Bean

    1、创建一个XML文件,必须以<beans>元素为根,最为简单的Spring xml配置如下

    <?xml version="1.0" encoding="UTF-8"?>
    <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.xsd
          http://www.springframework.org/schema/context">
    
    </beans>
    

    2、声明一个简单的<bean>

    // 默认的ID"soundsystem.SgtPeppers#0","#0"是一个计数形式
    <bean class="soundsystem.SgePeppers" />
    // 为bena设置一个id
    <bean id="compactDisc" class="soundsystem.SgePeppers" />
    

      当spring发现这个<bean>元素时,它将会调用SgtPeppers的默认构造器来创建bean。需要注意的是,在这个简单的<bean>声明中,我们将bean的类型以字符串的形式设置在了class属性中。谁能保证设置给class属性的值是真正的类呢?Spring的XML配置并不能从编译器的类型检查中受益。即便它所引用的是实际的类型,如果你重命名了类,会发生什么呢?

    3、借助构造器注入初始化bean

    具体到构造器注入,有两种基本的配置方案可供选择:

    · <constructor-arg>元素

    · 使用spring 3.0所引用的c-命名空间

    3.1、构造器注入bean引用

    
    
    <bean id ="cdPlayer" class="soundsystem.CDPlayer">
        <constructor-arg ref="compactDisc" />
    </bean>
    
    
    

      当spring遇到<bean>元素时,他会创建一个CDPlayer实例。<constructor-arg>元素会告知spring要将一个ID为compactDisc的bean引用传递到CDPlayer的构造器中。

    c-命名空间是在spring3.0中引入的,他是在XML中更为简洁第描述构造器参数的方式,要使用它必须要在XML的顶部声明其模式。

    <bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc">
    

    4、将字面变量注入到构造器中

    假设要创建CompactDisc的一个新实现

      

    <bean id="compactDIs" class="soundsystem.BlankDisc">
        <constructor-arg value="Sgt. Pepper's Loney Hearts Club Band" />
        <constructor-arg value="The Beatles" />
    </bean>
    

      这里没有使用“ref”属性来引用其他的bean,而是使用了value属性,通过该属性表明给定的值要以字面量的形式注入待构造器中(“ref”,引用传递,“value”,值传递)。

    5、设置属性

    如何选择构造器注入还是属性注入?对于强依赖使用构造器注入,二队可选性的依赖使用属性注入。

      

    <bean id="cdPlayer" class="soundsystem.CDPlayer">
        <property name="compactDisc" ref="compactDisc" />
    </bean>
    

      <property>元素为属性的Setter方法所提供的功能与<constructor-arg>元素为构造器所提供的功能是一样的。在本例中,它引用了ID为compactDisc的bean(通过ref属性),并将其注入到compactDisc属性中(通过setCompactDisc()方法)。

    spring为<constructoer-arg>元素提供了c-命名空间作为替代方案,与之类似,sping提供了更加简洁的p-命名空间,作为<property>元素的替代方案。

    使用p-命名空间需要进行声明:

      

    我们可以使用p-命名空间,按照以下的方式装配compactDisc属性

    <bean id="cdPlayer" class="soundsystem.CDPlayer" p:compactDisc-ref="compactDisc">
    

      "p:"前缀表明我们设置的是一个属性,属性名称以“-ref”提示spring要进行装备的是引用而不是字面量。

    将字面量注入到属性中

      

      

  • 相关阅读:
    【STM32F429开发板用户手册】第11章 STM32F429移植SEGGER的硬件异常分析
    【STM32F407开发板用户手册】第11章 STM32F407移植SEGGER的硬件异常分析
    【STM32F429开发板用户手册】第10章 STM32F429的FLASH,RAM和栈使用情况(map和htm文件)
    【STM32F407开发板用户手册】第10章 STM32F407的FLASH,RAM和栈使用情况(map和htm文件)
    【STM32F4029开发板用户手册】第9章 STM32F429重要知识点数据类型,变量和堆栈
    手写Mybatis插件
    Mybatis插件原理和整合Spring
    深入分析代理模式
    Mybatis源码(五)
    Mybatis源码(六)
  • 原文地址:https://www.cnblogs.com/wintercloud/p/10622374.html
Copyright © 2020-2023  润新知