zoukankan      html  css  js  c++  java
  • 装配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要进行装备的是引用而不是字面量。

    将字面量注入到属性中

      

      

  • 相关阅读:
    168. Excel Sheet Column Title
    171. Excel Sheet Column Number
    264. Ugly Number II java solutions
    152. Maximum Product Subarray java solutions
    309. Best Time to Buy and Sell Stock with Cooldown java solutions
    120. Triangle java solutions
    300. Longest Increasing Subsequence java solutions
    63. Unique Paths II java solutions
    221. Maximal Square java solutions
    279. Perfect Squares java solutions
  • 原文地址:https://www.cnblogs.com/wintercloud/p/10622374.html
Copyright © 2011-2022 走看看