装配Bean

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

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

 

1、自动化装配beanspring

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

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

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

二、@Component 注解代表该类会做为组件类,并告知spring要为这个类建立bean;组件扫描默认不启用,需组合@ComponentScan 注解使用。ui

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

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

五、设置组件扫描的基础包对象

@componetScan会以配置类所在的包做为基础包(base package)来扫描组件,若是咱们将配置类放在单独的包中,使其与其余的代码区分开来,就须要在@Component的value属性中指明包的名称:blog

@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{
}

  六、经过为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。

 

2、经过Java代码装配bean(JavaConfig)

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

二、声明简单的bean

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

三、借助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;
}

 

3、经过XML装配Bean

一、建立一个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>

二、声明一个简单的<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配置并不能从编译器的类型检查中受益。即使它所引用的是实际的类型,若是你重命名了类,会发生什么呢?

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

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

· <constructor-arg>元素

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

3.一、构造器注入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">

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

假设要建立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”,值传递)。

五、设置属性

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

  

<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要进行装备的是引用而不是字面量。

将字面量注入到属性中

  

  

相关文章
相关标签/搜索