《Spring实战》读书笔记——如何实现自动化装配

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

若是全部的装配工做都交给Spring来自动完成,减小人工的干预,是否是就能减小依赖关系配置带来的麻烦呢?认真作本身的事儿吧,装配交给Spring来!java

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

一览众山小

  • 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. 定义组件扫描的基础包微信

    若是咱们但愿把配置类与核心代码类放在不一样的包中,这时候默认的加载地址对咱们就没有意义了。这时候咱们能够自定义组件扫描的基础包。有如下两种方式:markdown

    (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就须要改变了。若是你设置了多个多个配置类,想一想,多么可怕?那么咱们来个更实用的。app

    (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的装配。一块儿期待吧!!!

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

相关文章
相关标签/搜索