《Spring3实战》摘要(3-2)--最小化Spring XML配置之自动检测Bean

3.3 自动检查 Bean

<context:annotation-config />可以帮助我们完全消除Spring配置中的<property><constructor-arg>元素,我们仍需要使用<bean>元素显式定义Bean。

<context:component-scan>元素除了能完成与<context:annotation-config />一样的工作外,还允许Spring自动检测 Bean 和定义Bean。这以为着不使用<bean>元素,spring应用中的大多数(或者所有)Bean都能够实现定义和装配。
这里写图片描述

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

注:base-package属性中的值只能精确到包,不能通过”.*”来精确到类,否则会找不到Bean

3.3.1 为自动检测标注Bean

默认情况下,<context:component-scan>元素查找使用构造型(stereotype)注解所标注的类,这些特殊的注解如下:

注解说明
@Component通用的构造型注解,标识该类为Spring组件。
@Controller标识将该类定义为 Spring MVC controller。
@Repository标识将该类定义为数据仓库。
@Service标识将该类定义为服务。


/**
 * Spring 扫描包时,会发现使用 @Component 注解所标注的Guitar,并自动地将它注册为 Spring Bean。Bean的ID默认为无限定类名。
 */
package com.springinaction.springidol;
import org.springframework.stereotype.Component
@Component
public class Guitar implements Instrument{
    ...
}

/**
 * 指定 Bean ID 作为 @Component 注解的参数。该 Bean 的 ID 不会被默认设置为类的名称 "instrumentalist",而是显示的命名为 eddie 。
 */
package com.springinaction.springidol;
import org.springframework.stereotype.Component
@Component("eddie")
public class Instrumentalist implements Performer {
    //...
}

3.3.2 过滤组件扫描

通过为 <context:component-scan> 配置 <context:include-filter> 和/或者 <context:exclude-filter> 子元素,我们可以随意调整扫描行为。

<!-- <context:include-filter>的type和expression属性一起协作来定义组件扫描策略。在这种情况下,我们要求派生于Instrument的所有类自动注册为Spring Bean。 -->
<context:component-scan base-package="com.springinaction.springidol">
    <context:include-filter type="assignable" expression="com.springinaction.springidol.Instrument" />
</context:component-scan>

<!-- 除了使用自定义 @SkipIt 注解的类,其他所有的Instrument实现都需要注册为 Spring Bean。 -->
<context:component-scan base-package="com.springinaction.springidol">
    <context:include-filter type="assignable" expression="com.springinaction.springidol.Instrument" />
    <context:exclude-filter type="annotation" expression="com.springinaction.springidol.SkipIt"/>
</context:component-scan>

使用5种过滤器类型的任意一种来自定义组件扫描方式:

过滤器类型描述
annotation过滤器扫描使用指定注解所标注的那些类,通过 expression 属性指定要扫描的注解
assignable过滤器扫描派生于expression属性所指定类型的那些类
aspectj过滤器扫描与expression属性所指定的AspectJ表达式所匹配的那些类
custom使用自定义的 org.springframework.core.type.TypeFilter 实现类,该类由expression属性指定
regex过滤器扫描类的名称与 expression 属性所指定的正则表达式所匹配的那些类

3.4 使用 Spring 基于 Java 的配置

Spring 3.0 提供使用Java代码来配置 Spring 应用的方式。

3.4.1 创建基于Java的配置

使用极少量的XML来启用Java配置:

<!-- <context:component-scan>会自动加载使用 @Configuration 注解所标注的类。在该示例中,base-package属性告知 Spring 在 com.springinaction.springidol 包内查找使用 @Configuration 注解所标注的所有类。 -->
<?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-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-lazy-init="true">

        <context:component-scan base-package="com.springinaction.springidol" />
</beans>

3.4.2 定义一个配置类

在基于 Java 的配置里使用 @Configuration 注解的 Java 类,就等价与 XML 配置中的 <beans>元素。@Configuration 注解会作为一个标识告知Spring:这个类将包含一个或多个 Spring Bean 的定义。这些 Bean 的定义是使用 @Bean 注解所标注的方法。

import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringIdolConfig {

    // Bean declaration methods go here

}

3.4.3 声明一个简单的Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringIdolConfig {
    <!-- 基于Java的配置来装配 Bean ID 为 "duke" 的Bean -->
    @Bean
    public Performer duke(){
        return new Juggler();
    }
}

3.4.4 使用 Spring 的基于 Java 的配置进行注入

//示例1,注入数值型参数15
@Bean
public Performer duke15(){
    return new Juggler(15);
}

//示例2,注入字符串型参数
@Bean
public Performer kenny(){
    Instrumentalist kenny = new Instrumentslist();
    kenny.setSong("Jingle Bells");
    return kenny;
}

//示例3,注入其他Bean引用。在 Spring 的 Java 配置中,通过声明方法引用一个 Bean 并不等同于调用该方法。通过使用 @Bean 注解标注 sonnet29() 方法,会告知 Spring 我们希望该方法定义的 Bean 要被注册进 Spring 的应用上下文中。因此,在其他 Bean 的声明方法中引用这个方法时,Spring 都会拦截该方法的调用,并尝试在应用上下文查找该 Bean,而不是让方法创建一个新的实例。
@Bean
private Poem sonnet29(){
    return new Sonnet29();
}

@Bean
public Performer poeticDuke(){
    return new PoeticJuggler(sonnet29());
}   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值