[Spring]04_最小化Spring XML配置

4.1 自动装配 Bean



Spring 装配 bean 时,有时非常明确,就是需要将某个 bean 的引用装配给指定属性。

例如,若应用上下文中只有一个 javax.sql.DataSource 类型的 bean,那么任意一个依赖 DataSource 的其他 bean 就是需要这个 DataSource Bean。

为了应对这种明确的装配场景,Spring提供了自动装配(autowiring)。

4.1.1 四种类型的自动装配

Spring提供了4种自动装配策略

(1)byName——把与 Bean 的属性具有相同名字(或者ID)的其他 Bean 自动装配到 Bean 的对应属性中。如果没有跟属性的名字相匹配的 Bean, 则该属性不进行装配。

(2)byType——把与 Bean 的属性具有相同类型的其他 Bean 自动装配到 Bean 的对应属性中。如果没有跟属性的类型相匹配的 Bean,则该属性不被装配。

(3)constructor——把与 Bean 的构造器入参具有相同类型的其他 Bean 自动装配到 Bean 构造器的对应入参中。

(4)autodetect——首先尝试使用 constructor 进行自动装配。如果失败,再尝试使用 byType 进行自动装配。

在 Spring 中,使用自动装配的方式是在 bean 元素中注明 autowire 属性。

以 byName 为例

假如有一个歌手类,含两个属性,一个是演唱的曲目,一个是演奏的乐器。

<bean id="jack" class="com.spring.demo.Singer">
    <property name="song" value="Star" />
    <property name="instrument" ref="guitar" />
</bean>

以上,是显示配置 instrument 的方法。

如果,定义定义吉他(Guitar) Bean 时,把 Bean 的 id 属性设置为 instrument:

<bean id="instrument" class="com.spring.demo.Guitar" />

可以发现Guitar Bean的 id 属性和 Singer Bean 的 name 属性的名字是一样的。

Spring 可以通过配置 autowire 属性,将两者自动关联起来,如下:

<bean id="jack" class="com.spring.demo.Singer" autowire="byName">
    <property name="song" value="Star" />
</bean>

完成。

其他自动装配类型的使用方式和 byName 差不多,这里不再赘述。

4.1.2 默认自动装配

你是否会觉得给每一个 bean 都设置相同的 autowire 类型过于麻烦?

Spring允许在根元素 <beans> 上使用 fault-autowire 属性来设置所有 bean 的默认自动装配属性。

<?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-3.0.xsd"
    default-autowire="byType">
</beans>

在上例中, <beans> 标签下的所有 bean 如果不显示的指定 autowire 属性,那么它们的默认自动装配属性都是 byType 类型。

4.2 使用注解装配



从 Spring2.5 开始,引入了注解,从此可以使用注解自动装配 Bean 的属性。

使用注解方式自动装配与在XML中使用 autowire 属性自动装配并没有太大区别,但是使用注解方式允许更细粒度的自动装配。

注意:Spring默认禁用注解装配,所以要使用它,必须先使用 <context:annotation-config> 来启用注解配置。

Spring3 支持几种不同的用于自动装配的注解:

  • Spring自带的 @Autowired 注解
  • JSR-330 的 @Inject 注解
  • JSR-250 的 @Resource 注解

4.2.1 @Autowired

对方法进行标注

@Autowired 可以标注需要自动装配Bean引用的任意方法(set方法、普通方法、构造方法)。

public class Audience {
    private Movie movie;
    
    // 标注构造方法
    @Autowired
    public Audience(Movie movie) {
        this.movie = movie;
    }

// 标注set方法
    @Autowired
    public void setMovie(Movie movie) {
        this.movie = movie;
    }
    
    // 标注构造方法
    public void watchMovie(Movie movie) {
        this.movie = movie;
        System.out.println("Watch " + movie.toString());
    }
}

对属性进行标注

可以使用 @Autowired 直接标注属性,并删除 setter 方法。

@Autowired
private Movie movie;

@Autowired 不会受限于 private 关键字,即使属性是私有的,它仍然可以被自动装配。

可选的自动装配

默认情况下,@Autowired 具有强契约特征,其所标注的属性或参数必须是可装配的。

如果没有 Bean 可以装配到 @Autowired 所标注的属性或参数中,自动装配失败,抛出 NoSuchBeanDefinitionException

如果,属性不一定非要装配,null 值也是可以接受的。这种情况下,可以通过设置 @Autowiredrequired 属性为 false 来配置自动装配是可选的。

@Autowired(required=false)
private Movie movie;

注意:require 属性可以用于 @Autowired 所使用的任意地方。

但是,当使用构造器装配时,只有一个构造器可以将 @Autowired 的 required 属性设置为 true,其他的只能置为 false。

@Qualifier

如果有多个 Bean 完全满足装配条件,并且都可以被装配到属性或参数中。在这种情况下,@Autowired 注解没有办法选择哪一个

Bean 才是真正需要的。这时,可以使用 @Qualifier 注解来缩小选择范围。

@Autowired
@Qualifier("cartoon")
private Movie movie;

以上所示,@Qualifier 尝试注入ID为 cartoon 的 Bean。

创建自定义的Qualifier

如下演示了如何自定义一个限定器:

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface PrivateMovie {
}

有了自定义的注解,就可以用它来代替 @Qualifier:

@Autowired
@PrivateMovie
private Movie movie;

4.2.2 @Inject

@Inject 注解是 JSR-330 的核心部件。该注解几乎可以完全替换 Spring 的 @Autowired 注解。

和 @Autowired 一样,@Inject 可以用来自动装配属性、方法和构造器。

与 @Autowired 不同的是,@Inject 没有 required 属性。因此,@Inject 注解所标注的依赖关系必须存在,如果不存在,则会抛出异常。

Provider

JSR-330中有个技巧:不直接注入一个引用,而是注入一个 Provider,Provider 接口可以实现 Bean 引用的延迟注入以及注入 Bean 的多个实例等功能。

4.3 自动检测 Bean



<context:annotation-config> 有助于完全消除 Spring 配置的 <property><constructor-arg> 元素,但是仍然需要使用 <bean> 元素显示定义 Bean。

<context:component-scan> 除了完成与 <context:annotation-config> 一样的工作,还允许 Spring 自动检测 Bean 和定义 Bean。

<?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"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context   
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<context:component-scan base-packet="com.spring.demo">
    </context:component-scan>
</beans>

<context:component-scan> 元素会扫描指定的包及其所有子包,并查找出能够自动注册为 Spring Bean 的类。

base-package 属性标识了 <context:component-scan> 元素所扫描的包。

4.3.1 为自动检测标注 Bean

默认情况下,<context:component-scan> 查找使用构造器注解所标注的类。

这些特殊的注解如下:

  • @Component
  • @Controller
  • @Repository
  • @Service
  • 使用@Component标注的任意自定义注解

4.3.2 过滤组件扫描

<context:component-scan> 中有两个子元素,可以用来调整扫描行为:

  • <context:include-filter>——包含过滤器
  • <context:exclude-filter>——排除过滤器

<context:component-scan base-packet="com.spring.demo">
    <context:include-filter type="assignable" expression="com.spring.demo.Movie" />
</context:component-scan>

上例中的,typeexpression 属性一起协作来定义组件扫描策略。

type 有五种选择:


过滤器类型


描述


annotation


过滤器扫描使用指定注解所标注的那些类。通过 expression 属性指定要扫描的注解


assignable


过滤器扫描派生于 expression 属性所指定类型的那些类


aspectj


过滤器扫描与 expression 属性所指定的 AspectJ 表达式所匹配的那些类


custom


使用自定义的org.springframework.core.type.TypeFilter 实现类,该类由 expression 属性指定


regex


过滤器扫描类的名称与 expression 属性所指定的正则表达式所匹配的那些类

参考资料



Spring实战(第3版)

时间: 2024-08-28 09:54:40

[Spring]04_最小化Spring XML配置的相关文章

centos6.x最小化安装后配置网络

centos6.x最小化安装后配置网络 最小化安装CentOS6.x后,试着用yum安装几个软件,发现网卡都没配置! 解决办法: 编辑配置文件: vi /etc/sysconfig/network-script/ifcfg-eth0 修改下列几项配置: NM_CONTROLLED=no ONBOOT=yes BOOTPROTO=dhcp 修改完保存,然后: service network start 启动网卡,yum能用了!

Linux最小化安装网络配置

Linux最小化安装网络配置 配置网络ip vi /etc/sysconfig/network-scripts/ifcfg-ens33(将选中的部分改为yes) 保存退出并重启网络 service network restart 3.最小化安装没有ifconfig要用ip addr查看ip地址 ssh连接到MobaXterm 下载dokuwiki前安装必要工具 安装vimyum -y install vim 安装wgetyum -y install wget 安装net-tools(已安装过)

Spring学习篇02-Bean的xml配置

1.bean标签 在Spring中,要在xml中配置一个bean,必须使用bean标签这个标签包含了要两个重要的属性: id:对bean进行标记在容器中是唯一的 class:bean的类类型 scope:表示该bean的实例个数,默认为单例. 2.property标签 property是bean的子标签,通过它可以向bean实例的属性进行注入,重要属性如下: name:对应类的属性 value:要注入类属性的原始值 ref:要注入类属性的引用bean的id property里面可以包含bean的

Spring定时器技术终结者——采用XML配置的方式实现Spring定时器

在Spring中有两种方式可以实现定时器的功能,分别是Scheduled注释方式和XML配置方式,本博客将介绍如何在Spring中使用采用XML配置的方式实现定时器的功能,代码及相应的解释如下: 代码1-Spring配置文件(applicationContext.xml文件): <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.o

spring Ioc容器之使用XML配置Bean

1.项目截图 2.创建xml文件 3.打印机接口 package com.example.demo.computerTest; public interface Printer { void init(); void print(String txt); } 4.彩色打印机 package com.example.demo.computerTest; public class ColorPrinter implements Printer { @Override public void init

【Linux】CentOS6.X最小化安装后配置

1.centos6.5最小化安装后启动网卡2.ifconfig查询IP进行SSH链接3.更新系统源并且升级系统4.系统时间更新和设定定时任5.修改ip地址.网关.主机名.DNS6.关闭selinux,清空iptables7.创建普通用户并进行sudo授权管理8.修改SSH端口号和屏蔽root账号远程登陆9.锁定关键文件系统(禁止非授权用户获得权限)10.精简开机自启动服务11.调整系统文件描述符大小12.设置系统字符集13.清理登陆的时候显示的系统及内核版本14.内核参数优化15.定时清理/va

Centos7最小化系统安装_配置

本文总结了作者使用centos最小化安装时,碰到的问题和解决方案. 网络问题.作者使用虚拟机安装时,网卡并没有激活.操作: 1 cd /etc/sysconfig/network-script 2 vi 要编辑的网卡 3 更改 onboot = yes 4 # 重启network 5 systemctl restart network 使用ip address命令查看IP地址 使用XSHELL远程连接虚拟机 1 #检测SSHD服务是否开启 2 systemctl status sshd 3 #如

安装最小化Linux,配置桌面

碰到个问题,有一个机子装了vmware sphere,然后装了几个linux虚拟机,但都是最小化版本,经了解后是无法安装图形化桌面,centos6.5和6.7都无法安装,只能装最小化,然后决定给最小化Linux配置桌面 使用yum源配置桌面 安装桌面组 yum -y groupinstall desktop 无法联网可以配置本地yum源 [[email protected] /]# mount /dev/cdrom /mnt mount: block device /dev/sr0 is wri

virtualbox 最小化安装centos7 配置双网卡(nat和桥接)记录----已经过期

该文章已经过期 请参考另一篇文章:virtualbox 安装centos7 配置桥接网卡,实现主机和虚拟机互通,虚拟机可以访问外网,解决无法上网问题 先说明一下为什么要配置双网卡? 配置nat网络, 虚拟机可以通过主机访问外网, 通过桥接网络, 虚拟机绑定静态ip,可以和其他虚拟机通信 改正:虚拟机可以通过配置一个桥接网卡,访问外网, 不需要配置两个网卡 最小化安装后,nat网卡没有启用,需要修改ifcfg-enp0s3 [[email protected] network-scripts]#