加我微信公众号,一起夯实Java基础,向着诗和远方出发吧~

如果所有的装配工作都交给Spring来自动完成,减少人工的干预,是不是就能减少依赖关系配置带来的麻烦呢?认真做自己的事儿吧,装配交给Spring来!

通过使用Spring的自动装配,我们不再需要去管对象之间复杂的依赖关系,能更加专注于应用核心逻辑的开发。接下来进入个人的free style!各位观众把锅接好了!

一览众山小

  • Spring开启组件扫描的方式
  • 如何让Bean能够被Spring扫描到
  • 怎么让Bean进行自动装配
  • 总结

Spring通过组件扫描和自动装配实现自动化装配Bean,通过自动化装配,能最大程度的减少各种显式配置。

Spring开启组件扫描的方式

组件扫描默认是不开启的,因此需要我们手动去启动。Spring开启组件扫描有以下两种方式。

通过Java配置类
  1. 基本示例
package com.lurker.springaction.yjiang.autowire;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
* 通过@Configuration注解,说明该类是一个配置类,配置信息从这里加载
* 通过@ComponentScan注解,说明开启组件扫描,默认扫描的是该配置类所在包及其子包
*/
@Configuration
@ComponentScan
public class ComponentScanConfig { }
  1. 定义组件扫描的基础包

    如果我们希望把配置类与核心代码类放在不同的包中,这时候默认的加载地址对我们就没有意义了。这时候我们可以自定义组件扫描的基础包。有以下两种方式:

    (1) 指明需要扫描的包的名称

    package com.lurker.springaction.yjiang.autowire;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration; @Configuration
    //指明扫描com.lurker.springaction.yjiang.autowire包
    //或者不用value,而使用basePackages,效果是一样的
    //value和basePackages都支持以数组的形式配置
    //示例:value={"com.lurker.springaction.yjiang.autowire", "..."}
    @ComponentScan(value = "com.lurker.springaction.yjiang.autowire")
    public class ComponentScanConfig { }

    但是以上方式有个明显的缺陷,其是类型不安全的,如果某次重构代码的时候,包名可能会改变,那么这里设置的valuebasePackages就需要改变了。如果你设置了多个多个配置类,想想,多么可怕?那么我们来个更实用的。

    (2) 指明需要扫描的包中的某个接口

    package com.lurker.springaction.yjiang.autowire;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration; //通过basePackageClasses属性,指明需要扫描的包中的接口
    //该方式同样支持以数组的形式配置
    //示例basePackageClasses={BasePackageLocation.class, ...}
    @Configuration
    @ComponentScan(basePackageClasses = BasePackageLocation.class)
    public class ComponentScanConfig { }

    以上方式,用basePackageClasses代替了valuebasePackages属性。程序在解析的时候,会以BasePackageLocation类所在的路径作为基础包路径。

    我们一般采用第二种方式进行配置,通常的做法是,在需要扫描的包下建立一个空接口,什么都不写。通过标记接口的形式找到基础包,同时由于是空接口,你在重构时可以不加理会,这种方式是对重构友好的。

通过XML文件配置

通过在Spring的xml配置文件中添加如下元素:

<context:component-scan base-package="com.lurker.springaction.yjiang.autowire">

通过这种方式能够取得跟Java配置相同的效果。同时,这种方式也支持同时配置多个包。

如何让Bean能够被Spring扫描到

开启了Spring的组件扫描之后,可以进行扫描指定的包及其子包了。那么,Spring怎么知道哪些才是Bean呢?实际上,Spring的组件是有一个标志的。

package com.lurker.springaction.yjiang.autowire;

import org.springframework.stereotype.Component;

//@Component注解表示该类会作为一个组件类,并告诉Spring要为这个类创建Bean
@Component
public class CDPlayer implements Player {
}

除了@Component注解外,还有三个注解同样拥有@Component的作用,他们分别是:

  • @Controller:注解Controller层
  • @Service:注解Service层
  • @Repository:注解DAO层

这三个注解继承自@Component注解,因此具有相同的功效。在分层架构体系下,在不同的层级运用不同名称的注解,使项目结构更加清晰。

然而注意,这些标注组件的注解,会默认给组件一个名称,默认为类名首字母小写,如其上的Bean名称为cDPlayer;Java中是允许在不同的包中有相同类名的,这时候怎么区分具有相同类名的Bean呢?Spring的解决方案是:

@Component@Controller@Service@Repository这些注解中,填写value字段,如下:

package com.lurker.springaction.yjiang.autowire;

import org.springframework.stereotype.Component;

//@Component注解表示该类会作为一个组件类,并告诉Spring要为这个类创建Bean
@Component(value="player")
public class CDPlayer implements Player {
}

以上代码,把这个Bean的名称定义为player,而不再是默认名称cDPlayer了。除此之外,JDI规范(Java Dependency Injection)还定义了@Named注解用于为Bean设置ID,其具有与@Component(value="player")相同的功效。例如:

@Named(value="player")
public class CDPlayer implements Player {
}

如何让Bean实现自动装配

万事俱备,只欠东风。Spring已经扫描到了进行标注后的Bean,并已经将他们放入容器中了,怎么把Bean装配到需要的地方呢?

Spring通过@Autowired注解来实现Bean的自动装配。@Autowired注解可以用在类的任何地方。但是,请注意,如果在装配过程中,如果某个需要的Bean不存在,那么Spring会抛出一个异常。如果这个欠缺的Bean不是那么重要,那么你可以尝试通过required设置为false来忽略掉它不存在的事实。

  1. 注解在构造方法上
package com.lurker.springaction.yjiang.autowire;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class CDPlayer { private Disk disk; @Autowired
public CDPlayer(Disk disk) {
this.disk = disk;
} public Disk getDisk() {
return disk;
} public void setDisk(Disk disk) {
this.disk = disk;
}
}
  1. 注解在setter方法上
package com.lurker.springaction.yjiang.autowire;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class CDPlayer { private Disk disk; public CDPlayer(Disk disk) {
this.disk = disk;
} public Disk getDisk() {
return disk;
} @Autowired
public void setDisk(Disk disk) {
this.disk = disk;
}
}
  1. 注解在属性上
package com.lurker.springaction.yjiang.autowire;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class CDPlayer { @Autowired
private Disk disk; public CDPlayer(Disk disk) {
this.disk = disk;
} public Disk getDisk() {
return disk;
} public void setDisk(Disk disk) {
this.disk = disk;
}
}
  1. 注解在任意方法上
package com.lurker.springaction.yjiang.autowire;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class CDPlayer { @Autowired
public void play(Disk disk) {
System.out.println(disk.toString());
} }
  1. 忽视某个Bean不存在的事实
package com.lurker.springaction.yjiang.autowire;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; @Component
public class CDPlayer { @Autowired(required=false)
public void play(Disk disk) {
System.out.println(disk.toString());
} }

除此之外,JDI也提供了@Inject来实现和@Autowired相同的功能。如果你不想太依赖Spring的注解的话,也可以使用@Inject注解来实现自动装配。

总结

本文,我们与代码结合,实现了Bean的自动化装配。实际上,这样做我们通过极少的配置就能够让Spring帮我们进行Bean的管理,何乐而不为呢?这种配置方式也是我们主推的。

下一节,我们将一起探讨通过Java配置的方式来进行Bean的装配。一起期待吧!!!

生命不止,学习不休,加油!!!

《Spring实战》读书笔记——如何实现自动化装配的更多相关文章

  1. Spring实战读书笔记

    Spring实战读书笔记 Spring-core Spring之旅 - DI 和 AOP 概念 spring 的Bean容器 spring 的 核心模块 Spring的核心策略 POJO 最小侵入式编 ...

  2. <<Java RESTful Web Service实战>> 读书笔记

    <<Java RESTful Web Service实战>> 读书笔记 第一章   JAX-RS2.0入门 REST (Representational State ransf ...

  3. 机器学习实战 - 读书笔记(13) - 利用PCA来简化数据

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第13章 - 利用PCA来简化数据. 这里介绍,机器学习中的降维技术,可简化样品数据. ...

  4. 机器学习实战 - 读书笔记(12) - 使用FP-growth算法来高效发现频繁项集

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...

  5. 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...

  6. 机器学习实战 - 读书笔记(07) - 利用AdaBoost元算法提高分类性能

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习笔记,这次是第7章 - 利用AdaBoost元算法提高分类性能. 核心思想 在使用某个特定的算法是, ...

  7. iPhone与iPad开发实战读书笔记

    iPhone开发一些读书笔记 手机应用分类1.教育工具2.生活工具3.社交应用4.定位工具5.游戏6.报纸和杂志的阅读器7.移动办公应用8.财经工具9.手机购物应用10.风景区相关应用11.旅游相关的 ...

  8. Spring 3.x 实践 第一个例子(Spring 3.x 企业应用开发实战读书笔记第二章)

    前言:工作之后一直在搞android,现在需要更多和后台的人员交涉,技术栈不一样,难免鸡同鸭讲,所以稍稍学习下. 这个例子取自于<Spring 3.x 企业应用开发实战>一书中的第二章,I ...

  9. spring实战学习笔记(一)spring装配bean

    最近在学习spring boot 发现对某些注解不是很深入的了解.看技术书给出的实例 会很疑惑为什么要用这个注解? 这个注解的作用?有其他相同作用的注解吗?这个注解的运行机制是什么?等等 spring ...

随机推荐

  1. There are multiple modules with names that only differ in casing. 黄色warning

    There are multiple modules with names that only differ in casing.有多个模块同名仅大小写不同This can lead to unexp ...

  2. REST(Representational state transfer)的四个级别以及HATEOAS介绍

    Rest RES(Representational state transfer):表现层状态转移.其实它省略了主语,「表现层」其实指的是「资源」的「表现层」,所以通俗来讲就是:资源在网络中以某种表现 ...

  3. php 查询mysql数据批量转为PDF文件二(批量使用wkhtmltopdf html导出PDF)

    上节讲到配置wkhtmltopdf,这节讲下如何批量操作 首先讲下wkhtmltopdf如何使用 直接命令行输入: wkhtmltopdf http://www.baidu.com/  baidu.p ...

  4. CentOS 7安装部署ELK 6.2.4-SUCCESS

    一.ELK介绍 ELK是三款开源软件的缩写,即:ElasticSearch + Logstash + Kibana.这三个工具组合形成了一套实用.易用的监控架构,可抓取系统日志.apache日志.ng ...

  5. elasticsearch基本使用

    elasticsearch 是java对lucence的封装,所以需要事先安装java. 它适用于全文索引,便捷的分布式,主要原理就是倒排索引.一般搜索某个关键字,是通过在一篇篇文章中查找这个关键字, ...

  6. js求最大值最小值

    比较数组中数值的大小是比较常见的操作,比较大小的方法有多种,比如可以使用自带的sort()函数,代码如下: <html> <head> <meta charset=&qu ...

  7. MySQL中MyISAM与InnoDB区别

    原文:https://blog.csdn.net/frycn/article/details/70158313?utm_source=copy InnoDB:支持事务处理等不加锁读取支持外键支持行锁不 ...

  8. angular 定时函数

    注入$interval,$timeout   服务 2.定义函数 var aa = $interval(function(){ $timout(function(){ ..... }) },,定时时间 ...

  9. 构建Spring Cloud微服务分布式云架构

    大型企业分布式微服务云架构服务组件 实现模块化.微服务化.原子化.灰度发布.持续集成 commonservice zipkinSpring 日志收集工具包,封装了Dapper和log-based追踪以 ...

  10. JS---作用域和作用域链

    JS---作用域和作用域链 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期.在JavaScript中,变量的作用域有全局作用域和局部作用域两种. //常犯的一个错误 &l ...