`
javawangli
  • 浏览: 224082 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring 中Bean的自动装配六种模式,你懂得几种?

阅读更多

       Spring Bean的自动装配六种模式,你懂得几种?

  

       Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系。因此,如果可能的话,可以自动让Spring通过检查BeanFactory中的内容,来替我们指定bean的协作者(其他被依赖的bean)。autowire一共有种类型。由于autowire可以针对单个bean进行设置,因此可以让有些bean使用autowire,有些bean不采用。autowire的方便之处在减少或者消除属性或构造器参数的设置,这样可以给我们的配置文件减减肥![2xml配置文件中,可以在<bean/>元素中使用autowire属性指定:

 

 

 

模式

说明

  Default

在每个bean中都一个autowire=default的默认配置它的含义是:

采用beans和跟标签中的default-autowire="属性值"一样的设置。

 

  On

不使用自动装配,必须通过ref元素指定依赖,默认设置。

 

  ByNname

根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。例如,在bean定义中将autowire设置为by name,而该bean包含master属性(同时提供setMaster(..)方法),Spring就会查找名为masterbean定义,并用它来装配给master属性。

  Bytype

如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则什么事都不发生,属性也不会被设置。如果你不希望这样,那么可以通过设置dependency-check="objects"Spring抛出异常。

 

 Constructor

byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。 

Antodetect

通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式

 

 

 

 

 

 

 

下来我们就用案例来证明一下:准备3个类:

 

 

public class AddressServiceImpl { 

/**住址*/

private String address; 

public void setAddress(String address){

this.address=address;

}

}



public class HomeAddressServiceImpl extends AddressServiceImpl {


private String address;


public void setAddress(String address){

this.address=address;

}


public HomeAddressServiceImpl() {

super();

}

public HomeAddressServiceImpl(String address){

this.address=address;

}


}



public class EmpServiceImpl {


/**公司地址*/

private AddressServiceImpl companyAddress;



public void setCompanyAddress(AddressServiceImpl companyAddress){

this.companyAddress=companyAddress;

}

}

 

1defaultnodefault.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-2.0.xsd"

default-autowire="no">

<bean id="homeAddressServiceImpl" class="cn.csdn.service.HomeAddressServiceImpl"

scope="singleton">

<property name="address">

<value>北京海淀上地软件园</value>

</property> 

</bean>

<bean id="empServiceImpl" class="cn.csdn.service.EmpServiceImpl"

scope="singleton" autowire="default" />

</beans>

 

 

 

 

 

 测试类:(junit测试)  

 

 

 public class App { 

@Test

public void test(){

ApplicationContext ac= new ClassPathXmlApplicationContext("classpath:default.xml"); EmpServiceImpl emp = (EmpServiceImpl) ac.getBean("empServiceImpl");

}

}

 

 声明:

<bean id="empServiceImpl" class="cn.csdn.service.EmpServiceImpl"

scope="singleton" autowire="no" />

不使用自动装配,必须通过ref元素指定依赖,默认设置。

 

  

 

 

 

2,byName值的byname.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-2.0.xsd">

<bean id="homeAddressServiceImpl" class="cn.csdn.service.HomeAddressServiceImpl"

scope="singleton">

<property name="address">

<value>北京海淀上地软件园</value>

</property> 

</bean>

<bean id="empServiceImpl" class="cn.csdn.service.EmpServiceImpl"

scope="singleton" autowire="byName" />

</beans>

 

 

 

 测试类:(junit测试)  

 

 public class App { 

@Test

public void test(){

ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:byName.xml"); EmpServiceImpl emp = (EmpServiceImpl) ac.getBean("empServiceImpl");

}

}

 

 

3,byTypebytype.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-2.0.xsd">

<bean id="homeAddressServiceImpl" class="cn.csdn.service.HomeAddressServiceImpl"

scope="singleton">

<property name="address">

<value>北京海淀上地软件园</value>

</property> 

</bean>


<bean id="empServiceImpl" class="cn.csdn.service.EmpServiceImpl"

scope="singleton" autowire="byType" />



</beans>

 

 

 

 

注意异常:

 

 

<beanid="addressServiceImpl"class="cn.csdn.service.AddressServiceImpl" scope="singleton"/>

//homeAddressServiceImpl是继承addressServiceImpl,所以他们是同一类型!


<!--  当有多个相同类型的bean时,会出现bug如下:

   org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'empServiceImpl' defined in file [D:\Workspaces\MyEclipse 8.6\20110419_01\bin\applicationContext.xml]: Unsatisfied dependency expressed through bean property 'companyAddress': : No unique bean of type [cn.csdn.service.AddressServiceImpl] is defined: expected single matching bean but found 2: [homeAddressServiceImpl, addressServiceImpl]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [cn.csdn.service.AddressServiceImpl] is defined: expected single matching bean but found 2: [homeAddressServiceImpl, addressServiceImpl]

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1091)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:982)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)

at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)

at java.security.AccessController.doPrivileged(Native Method)..........................

-->

 

 

 测试类:(junit测试)  

     

 public class App { 

@Test

public void test(){

ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:byName.xml"); EmpServiceImpl emp = (EmpServiceImpl) ac.getBean("empServiceImpl");

}

}

 

注意:

   byName byType

   在使用的过程中必须保证bean能够初始化,否则的话会出现bug

   如果有默认的无参数的构造器就不需要多余的配置

   如果有带有参数的构造器,那在bean的配置中必须配置器初始化的参数 或者在bean中添加无参数的构造器

 

 

4, Constructor值的constructor.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-2.0.xsd"> 

<!-- 配置bean  相同类型只能在 配置文件中出现一次

<bean id="homeAddressServiceImpl" class="cn.csdn.service.HomeAddressServiceImpl" scope="prototype">

  <property name="address">

    <value>北京</value>

  </property>

</bean>

<!-- 自动装配 采用constructor 构造器中的参数是按照byType进行装配的

<bean id="empServiceImpl" class="cn.csdn.service.EmpServiceImpl" scope="singleton" autowire="constructor"/>

</beans>

 

 

 测试类:(junit测试)  

     

 public class App { 

@Test

public void test(){

ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:byName.xml"); EmpServiceImpl emp = (EmpServiceImpl) ac.getBean("empServiceImpl");

}

}

 

5Antodetect值的antodetect.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-2.0.xsd"> 


<!-- 配置bean -->

<bean id="addressServiceImpl" class="cn.csdn.service.AddressServiceImpl" scope="singleton">

  <property name="address">

    <value>北京</value>

  </property>

</bean>

<bean id="empServiceImpl" class="cn.csdn.service.EmpServiceImpl" scope="singleton" autowire="autodetect"/>

</beans>

 

测试类:(junit测试)  

 

 public class App { 

@Test

public void test(){

ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:byName.xml"); EmpServiceImpl emp = (EmpServiceImpl) ac.getBean("empServiceImpl");

}

}

 

 

 

  

 

  结束语:  

 大部分学着都认为Bean的自动装配有5种模式,但详细的说是六种模式,他们往往忽略了default 值的应用,在每个bean中都一个autowire=default的默认配置它的含义是:采用beans和跟标签中的default-autowire="属性值"一样的设置,这个值是不能忽略的!

*可以设置bean使自动装配失效:
采用xml格式配置bean时,将<bean/>元素的autowire-candidate属性设置为false,这样容器在查找自动装配对象时,将不考虑该bean,即它不会被考虑作为其它bean自动装配的候选者,但是该bean本身还是可以使用自动装配来注入其它bean的。

 

<!--EndFragment-->

5
7
分享到:
评论
2 楼 dare_ 2014-09-23  
官网的文档明确说明 是五种 你的默认和no应该是同一种
1 楼 javawangli 2011-04-21  
[color=darkred][/color] 是不是大部分人认为有5种?但你你们忽略的往往是最重要的

相关推荐

    Spring实现自动装配

    在Spring 4中,自动装配主要有以下几种方式: 1. **无注解自动装配(No Annotation Auto-Wiring)**:在XML配置文件中,通过`&lt;context:component-scan&gt;`元素扫描指定包下所有的类,将它们声明为bean,并尝试自动...

    关于spring boot中几种注入方法的一些个人看法

    Spring Boot 中的几种注入方法 在 Spring Boot 中,注入是一种非常重要的机制,用于将 bean 对象注入到其他 bean 对象中,以便实现松耦合和高内聚的设计目标。下面我们将对 Spring Boot 中的几种注入方法进行详细的...

    spring自动装配

    Spring自动装配提供了几种模式来处理这些依赖,如`byName`、`byType`、`constructor`、`autodetect`和`default`。这些模式帮助Spring容器识别并注入合适的依赖。 - `byName`模式:根据属性名寻找匹配的Bean名称进行...

    spring装配bean的3种方式总结

    Spring装配Bean的3种方式总结 Spring框架是Java EE应用程序的核心框架之一,它提供了依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)等功能。依赖注入是Spring框架的核心...

    spring学习之四“自动装配”

    在Spring框架中,“自动装配”(Autowiring)是一项核心特性,它允许Spring容器自动为bean注入所需的依赖,而无需显式配置。本篇将深入探讨自动装配的概念、类型以及如何在Spring应用中使用。 自动装配是Spring IoC...

    spring自动装配项目struts2

    在这个"spring自动装配项目struts2"中,我们将探讨如何整合Spring的自动装配特性与Struts2框架,以及Hibernate作为持久层框架的使用。 首先,让我们了解Spring的自动装配(Auto-Wiring)。自动装配是Spring框架的...

    Spring中自动装配的4种方式

    下面将详细介绍 Spring 中的 4 种自动装配方式。 byName 自动装配 byName 自动装配是指通过设置 property 标签的 autowire 属性为 byName,Spring 将自动寻找一个与该属性名称相同或 id 相同的 Bean,注入进来。...

    Spring面试题.zip

    6、Spring 有几种配置方式? 7、如何用基于 XML 配置的方式配置 Spring? 8、如何用基于 Java 配置的方式配置 Spring? 9、怎样用注解的方式配置 Spring? 10、请解释 Spring Bean 的生命周期? 11、Spring Bean 的...

    第四章示例代码__自动装配

    在Spring中,自动装配有几种模式: 1. **byName**:Spring会查找与bean属性名称相匹配的bean,并将其注入。例如,如果有一个名为`dataSource`的属性,Spring将尝试找到一个名为`dataSource`的bean进行装配。 2. **...

    Spring中关于Bean的管理的课件

    在Spring框架中,Bean的管理是其核心特性之一,它涉及到Bean的创建、初始化、装配以及销毁等整个生命周期过程。本课件主要涵盖了以下几个关键知识点: 1. **控制反转(IoC)和依赖注入(DI)**:Spring的核心设计...

    Spring在应用中获得Bean的方法

    总结来说,Spring提供多种方式让我们在应用中获取Bean,包括直接通过名称、类型,或者利用注解实现自动装配。了解这些机制,有助于我们更好地理解和使用Spring框架,提高代码的可维护性和灵活性。同时,源码分析能...

    JSP Spring 自动化装配Bean实例详解

    Spring提供了几种自动装配模式: - **按类型装配(byType)**:Spring容器查找容器中匹配目标依赖类型的Bean,并将其注入到依赖对象中。如果有多个这样的Bean,则会抛出异常。 - **按名称装配(byName)**:Spring...

    Spring学习之Bean的装配多种方法

    在Spring框架中,Bean的装配是指将对象的创建交给第三方,并且由第三方进行注入的过程。Spring中的Ioc容器扮演着这样的一个角色,将对象的创建等交给Spring,而服务对象只管使用即可。配置Bean的过程其实也就是告诉...

    模拟Spring的IoC容器实现注解自动装配

    而注解自动装配(Autowired)是Spring IoC容器的一种高级特性,它允许我们通过注解来声明对象之间的依赖,无需手动编写XML配置。现在,我们将深入探讨如何模拟Spring的IoC容器实现注解自动装配。 首先,我们需要...

    Spring如何装配各种集合类型的属性

    例如,如果集合元素是`List&lt;Address&gt;`,且存在多个`Address`类型的bean,它们的名称分别与集合元素的类型匹配,如`homeAddress`、`workAddress`,那么这些bean会被自动装配到列表中。 6. **使用`@Qualifier`注解** ...

    Spring系列面试题129道(附答案解析)

    在该容器中,对象定义(通过配置文件或注解)被创建,并通过依赖注入的方式自动装配依赖项。 IOC容器通过管理对象的创建和它们之间的依赖关系,使得对象之间的耦合度降低。 72、IOC的优点是什么? IOC(控制反转)...

    Spring在代码中获取bean的几种方式.rar

    以下将详细介绍Spring在代码中获取bean的几种主要方法: 1. **`ApplicationContext` 接口** `ApplicationContext` 是Spring中最常用的接口之一,它提供了获取Bean的多种方法。例如,`getBean(String beanName)` ...

    第一章 Spring4 简介及获取Bean

    获取Bean主要有以下几种方式: 1. **通过Bean的ID**:使用`ApplicationContext`的`getBean()`方法,传入Bean的ID来获取实例。 2. **自动装配(Autowired)**:使用`@Autowired`注解,Spring会自动匹配类型匹配的...

    学习Spring的一点代码01:如何获取bean?

    Spring提供了多种方式来获取Bean,下面将详细介绍几种常用的方法。 1. **基于XML的配置** 在传统的Spring应用中,Bean定义通常存储在XML文件中。我们可以通过`ApplicationContext`接口的`getBean`方法来获取Bean。...

Global site tag (gtag.js) - Google Analytics