依赖注入

Spring主要提供以下两种方法用于依赖注入

  • 基于属性Setter方法注入
  • 基于构造方法注入

Setter方法注入

例子:

public class Communication {private Messaging messaging;/** DI via Setter*/public void setMessaging(Messaging messaging){this.messaging = messaging;}public void communicate(){messaging.sendMessage();}
}

如上Communication类有一个messaging属性,并含有setMessaging方法,那么使用Setter方法注入的时候,只需要使用如下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" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><bean id="activeMqMessaging" class="com.websystique.spring.domain.impl.ActiveMQMessaging" /><bean id="communication" class="com.websystique.spring.Communication"><property name="messaging"><ref bean="activeMqMessaging" /></property></bean></beans>

这里省略了ActiveMQMessaging的定义,实际上ActiveMQMessaging类是Messaging接口的一个实现类。

构造方法注入

例子

public class Communication {private Encryption encryption;/** DI via Constructor Injection*/public Communication(Encryption encryption){this.encryption = encryption;}public void communicate(){encryption.encryptData();}}

注意以上Communication类有一个构造方法Communication(Encryption encryption),且含有一个入参,类型为Encryption,那么使用构造方法注入的时候,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" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><bean id="rsaEncryption" class="com.websystique.spring.domain.impl.RSAEncryption" /><bean id="communication" class="com.websystique.spring.Communication"><constructor-arg type="com.websystique.spring.domain.Encryption"><ref bean="rsaEncryption" /></constructor-arg></bean></beans>

注意,这里省略了RSAEncryption的定义,不用在意这些细节,该类是Encryption接口的一个实现类。

另外,为了避免构造方法重载带来的歧义,这里指定了入参类型为com.websystique.spring.domain.Encryption。

装配

bean的装配有两种方式,手动装配和自动装配。注意,不要混淆,bean的装配是依赖注入的具体行为,依赖注入的时候需要根据bean的名称或类型等进行装配。

手动装配:通过在<property> 或者 <constructor>标签中使用ref属性,在上一小节的“依赖注入”部分使用的就是手动装配;

<!-- default example (autowire="no") -->
<bean id="driver" class="com.websystique.spring.domain.Driver"><property name="license" ref="license"/>
</bean><bean id="license" class="com.websystique.spring.domain.License" ><property name="number" value="123456ABCD"/>
</bean>

自动装配:在<bean>标签中使用autowire属性;

<bean id="application" class="com.websystique.spring.domain.Application" autowire="byName"/>

本小节主要关注自动装配,自动装配有以下四种方式:

  • autowire="byName" : 根据名称
  • autowire="byType" : 根据类型
  • autowire="constructor" : 根据构造方法入参类型
  • autowire="no" : 不使用自动装配,即默认方式,手动装配

autowire="byName"

例子:

public class Application {private ApplicationUser applicationUser;public ApplicationUser getApplicationUser() {return applicationUser;}public void setApplicationUser(ApplicationUser applicationUser) {this.applicationUser = applicationUser;}@Overridepublic String toString() {return "Application [applicationUser=" + applicationUser + "]";}
}

该类有一个属性叫applicationUser,那么根据名称自动装配的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" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- byName example --><bean id="application" class="com.websystique.spring.domain.Application" autowire="byName"/><bean id="applicationUser" class="com.websystique.spring.domain.ApplicationUser" ><property name="name" value="superUser"/></bean>
</beans>

autowire="byType"

例子

public class Employee {private EmployeeAddress address;public EmployeeAddress getAddress() {return address;}public void setAddress(EmployeeAddress address) {this.address = address;}@Overridepublic String toString() {return "Employee [address=" + address + "]";}
}

该类有一个属性类型为EmployeeAddress,那么根据类型自动装配的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" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- byType example --><bean id="employee" class="com.websystique.spring.domain.Employee" autowire="byType"/><bean id="employeeAddress" class="com.websystique.spring.domain.EmployeeAddress" ><property name="street" value="112/223,SantaVila"/><property name="city" value="Nebraska"/></bean></beans>

autowire="constructor"

例子

public class Performer {private Instrument instrument;public Performer(Instrument instrument){this.instrument = instrument;}@Overridepublic String toString() {return "Performer [instrument=" + instrument + "]";}
}

该类有一个构造方法,入参的类型为Instrument,那么根据构造方法自动装配的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" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- constructor example --><bean id="performer" class="com.websystique.spring.domain.Performer" autowire="constructor"/><bean id="instrument" class="com.websystique.spring.domain.Instrument" ><property name="name" value="PIANO"/></bean></beans>

autowire="no"

public class Driver {private License license;public void setLicense(License license) {this.license = license;}public License getLicense() {return license;}@Overridepublic String toString() {return "Driver [license=" + license + "]";}
}

该类有一个属性license,由于我们不打算使用自动装配功能,那么只能使用手动装配了,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" xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"><!-- default example (autowire="no") --><bean id="driver" class="com.websystique.spring.domain.Driver" autowire="no"><property name="license" ref="license"/></bean><bean id="license" class="com.websystique.spring.domain.License" ><property name="number" value="123456ABCD"/></bean></beans>

注意,如果不配置license的ref引用的话,license将为null。

相关注解

主要涉及以下三个注解

  • @Autowired
  • @Resource
  • @Qualifier

@Autowired可应用于构造方法、属性、setter方法或配置类@Configuration的方法上,该注解根据bean的数据类型进行装配,如果你想希望根据bean的名称进行装配可以使用带name属性的@Resource注解;另外@Qualifier注解经常与@Autowired注解结合使用,用于解决一个应用中存在多个同种类型的bean的情况,下面将给出各个注解的示例。

@Autowired(根据类型自动装配)

setter方法上

@Component("driver")
public class Driver {private License license;@Autowiredpublic void setLicense(License license) {this.license = license;}@Overridepublic String toString() {return "Driver [license=" + license + "]";}//getter
}

构造方法上

@Component("driver")
public class Driver {private License license;@Autowiredpublic Driver(License license){this.license = license;}@Overridepublic String toString() {return "Driver [license=" + license + "]";}
}

属性上

@Component("driver")
public class Driver {@Autowiredprivate License license;//getter,setter
 @Overridepublic String toString() {return "Driver [license=" + license + "]";}
}

@Resource(根据名称装配)

@Component("application")
public class Application {@Resource(name="applicationUser")private ApplicationUser user;@Overridepublic String toString() {return "Application [user=" + user + "]";}
}

@Qualifier(与@Autowired结合使用,实现按名称装配)

例子背景::存在两个Car接口的实现类,其中一个Car接口的实现类已被注册为bean,且name为Mustang

@Component
public class Bond {@Autowired@Qualifier("Mustang")private Car car;public void showCar(){car.getCarName();}
}

注意,以上例子如果不使用@Qualifier限定的话,将抛出如下异常,表明存在多个类型相同的bean:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.websystique.spring.domain.Car] is defined: expected single matching bean but found 2: Ferari,Mustang
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:970)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
    ... 14 more

最后提醒下,被@Autowired注解标注默认情况下能保证成功注入,如果注入不成功(往往是找不到,或存在歧义),Spring会抛出异常。当然,有时候可能会有特殊需求,不希望bean被强制装配,那么可以在@Autowired上添加required=false属性,表明该bean的装配是可选的,找不到的话,就为null吧,如下示例:

@Component("driver")
public class Driver {@Autowired(required=false)private License license;//getter,setter
 @Overridepublic String toString() {return "Driver [license=" + license + "]";}
}

基于以上原因,虽然@Autowired注解与@Resource功能类似,但是@Autowired还是比@Resource强大了那么一点点,个人建议使用@Autowired注解。

本文转自风一样的码农博客园博客,原文链接:http://www.cnblogs.com/chenpi/p/6222595.html,如需转载请自行联系原作者

Spring bean依赖注入、bean的装配及相关注解相关推荐

  1. 零配置 之 Spring 注解实现Bean依赖注入

    转载自  [第十二章]零配置 之 12.2 注解实现Bean依赖注入 --跟我学spring3 12.2  注解实现Bean依赖注入 12.2.1  概述 注解实现Bean配置主要用来进行如依赖注入. ...

  2. Spring Bean 依赖注入

    动注入 手动注入就是在XML中定义Bean时,给Bean的某个属性指定了值. set方法注入 <bean name="orderService" class="co ...

  3. Spring依赖注入与自动装配

    Spring依赖注入与自动装配 首先推荐狂神说的Spring讲义 1.Beans.xml作用 简而言之,我们通过在beans.xml中进行配置,将各种类交给spring来管理. 2.依赖注入 推荐狂神 ...

  4. Bean依赖注入的3种数据类型

    Bean依赖注入有3种类型,分别是普通数据类型.集合和引用数据类型. 在这里我主要用的set依赖注入方法 1.普通数据类型 public class Book{private String bid;p ...

  5. 05.bean依赖注入的三种方式

    05.bean依赖注入的三种方式 1.概述 依赖注入 DI(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现. 在编写程序时,通过控制反转,把对象的创建交给 ...

  6. Spring——Filter过滤器注入Bean时注入失败[NULL]

    问题描述 Spring中Filter注入Bean时注入失败,Bean一直为空. @Slf4j @Component public class RestAuthFilter extends FormAu ...

  7. Autowired,Qualifier,Spring 按名称注入bean属性

    Autowired,Qualifier,Spring 按名称注入bean属性 @Autowired@Qualifier("addItemDestination")private T ...

  8. java框架篇---spring IOC依赖注入

    spring依赖注入的方式有4种 构造方法注入 属性注入 工厂注入 注解注入 下面通过一个实例统一讲解: User.java package com.bjsxt.model;public class ...

  9. factorybean 代理类不能按照类型注入_《Spring入门经典》:使用Spring进行依赖注入

    第二章:使用Spring进行依赖注入 重点:配置并使用Spring容器 使用不同类型的配置元数据来配置Spring容器 理解依赖解析 了解自动装配的优缺点 在容器中执行显式Bean查找 学习不同的Be ...

  10. spring(一)依赖注入与 SPEL

    Spring之依赖注入与 SPEL 一.控制反转与依赖注入 二.helloworld 三.构造注入 四.级联注入 五.单例与多例 六.工厂方法创建 Bean 七.包扫描管理 bean 八.SPEL与资 ...

最新文章

  1. 博士如何高效率阅读文献?有哪些技巧可以借鉴?
  2. R语言stringr包str_detect函数检测字符串中模式存在与否实战
  3. 算法---------数组-----------翻转单链表
  4. C#操作Excel(NPOI)
  5. 【STM32】STM32F4时钟系统
  6. 牛客 - 云(扫描线)
  7. 华为手机30s桌面循环滑动_华为发飙了!麒麟820+双模5G,从2699元跌至2499元,超出消费者预期...
  8. 大数据分析实战-信用卡欺诈检测(三)- 模型评估
  9. 百度突然发公告:将停止这个服务!
  10. Spring : Transaction源码解析
  11. 将Windows8或WindowsServer2012装在VHD上
  12. VTK图形模型主要对象
  13. 联想微型计算机的摄像头驱动,Lenovo EasyCamera 联想摄像头驱动
  14. 计算机网络管理员路由与交换深圳积多少分,2020年深圳积分入户,哪些加分的证书总结?...
  15. Qt制作简易电子相册
  16. 周期性的方波 matlab,[转载]matlab产生方波脉冲和周期性方波信号
  17. 基于java拼图游戏(带文档)
  18. 斯坦福大学自然语言处理第七课“情感分析(Sentiment Analysis)”
  19. 重积分的计算机应用开题报告,重积分的数值计算【信息科学与技术专业】【毕业设计 文献综述 开题报告】.docx...
  20. 前端纯CSS导入otf字体包

热门文章

  1. python io流,Python io流会在列表理解中自动关闭吗?
  2. Android安全加密:Https编程
  3. Android 网络请求详解
  4. 安装配置Kali虚拟机----linux----kali
  5. Photoshop CC2015软件安装资料及教程
  6. python正则_Python基础12之Python正则
  7. C语言中printf是不是关键字,C语言中printf是什么意思
  8. ubuntu使用fail2ban_如何在Ubuntu 20.04上安装和配置Fail2ban
  9. mysql级联查询_mysql 各种级联查询后更新(update select)
  10. Apache Flink 简介和编程模型