3. 自动检测Bean

自动检测Bean

Spring提供 <context:component-scan> 元素,除了完成与 <context:annotation-config> 一样的工作,还可以自动检测和定义Bean。有了 <context:component-scan> 元素,可以不使用 <bean> 元素,Spring应用中的大多数Bean能实现定义和装配。

<?xml version="1.0" encoding="UTF-8"?>

<!-- 引用Spring的多个Schema空间的格式定义文件 -->

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 要开启自动检测,首先需要声明context命名空间并引入xsd文件,base-package表示在哪个包中进行自动检测 -->
    <context:component-scan base-package="com.li.spring.autowire"></context:component-scan>

</beans>

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

为自动检测标注Bean

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

  • @Component——通用型的构造型注解,表示该类为Spring组件

  • @Controller——标识将该类定义为Spring MVC controller

  • @Repository——将该类标识为数据仓库

  • @Service——标识将该类定义为服务

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

自动注解其Bean的id为首字母小写的类名,当然也可以通过注解的属性为其指定名称。

过滤组件扫描

通过 <context:component-scan> 配置 <context:include-filter>(包含过滤器)和 <context:exclude-filter>(排除过滤器)子元素,可以随意调整扫描策略。

<context:component-scan base-package="com.li.spring.autowire">
    <context:include-filter type="assignable" expression="com.li.spring.chineseidol.Instrument"/>
</context:component-scan>

<context:include-filter> 的type和expression属性一起协作来定义组件扫描策略。上例实现类要求派生于 com.li.spring.chineseidol.Instrument 的所有类自动注册为Spring Bean(其中 assignable 表示派生类型)。

过滤组件扫描

Filter Type Description
annotation 过滤器扫描使用指定注解所标注的类,使用的是express属性指定所要扫描的注解
assignable 过滤器扫描派生于expression属性所指定类的那些类
aspectj 过滤器扫描与expression属性所指定的aspectj表达式所匹配的那些类
custom 使用自定义的 org.springframeword.core.type.TypeFilter 实现类,此类由expression属性来指定
regex 过滤器扫描类的名称与expression表达式正则匹配的那些类

使用五种过滤器类型的任意一种来自定义组件扫描方式,还可以使用 <context:exclude-filter> 来告知 <context:component-scan> 哪些类不需要注册为Spring Bean。

使用示例

导弹接口,具备发射功能

package com.li.autowire;

/*导弹接口*/

public interface IMissile {

    void fire();
}

导弹接口的实现类,需要标注为Spring Bean

package com.li.autowire;

import org.springframework.stereotype.Component;

/*导弹类,实现导弹接口*/

@Component
public class Missile implements IMissile {

    @Override
    public void fire() {
        System.out.println("The missile is fired...");
    }   
}

具有发射导弹的无人机类,也需要注解为Spring Bean

package com.li.autowire;

import java.io.File;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

/*无人机类*/

@Component
public class Uav {

    /*无人机装配有导弹*/
    /*使用注解注入,则getter和setter方法可以不需要*/
    @Autowired
    private IMissile missile;

    @Value("B-2")
    private String type;

//  读取方法可以不需要
//  public IMissile getMissile() {
//      return missile;
//  }
//
//  public void setMissile(IMissile missile) {
//      this.missile = missile;
//  }

    public Uav(IMissile missile) {
        super();
        this.missile = missile;
    }

    public Uav() {
        super();
    }

    public void attack() {
        missile.fire();
    }

    @Override
    public String toString() {
        return "Uav [type=" + type + "]";
    }

    public static void main(String[] args) {
        ApplicationContext ctx=new ClassPathXmlApplicationContext("com"+File.separator+"li"+File.separator+"autowire"+File.separator+"uav.xml");
        Uav uav=(Uav)ctx.getBean("uav");
        uav.attack();
        System.out.println(uav.toString());;
    }
}

使用自动检测并无意味着我们就可以完全脱离XML配置文件了,我们还需要在XML配置文件中开启自动检测,但是已经无需在这里面配置Bean了(注意配置的base-package)。

<?xml version="1.0" encoding="UTF-8"?>

<!-- 引用Spring的多个Schema空间的格式定义文件 -->

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 开启自动解除,记住先在前面声明context命名空间 -->
    <context:component-scan base-package="com.li.autowire"></context:component-scan>

</beans>

猜你喜欢

转载自blog.csdn.net/sinat_37976731/article/details/81364546