spring註解開發:ComponentScan組件掃描

在使用xml方式配置時,咱們只須要在xml中配置以下代碼:
java

<context:component-scan base-package="包名"></context:component-scan>

那麼在java代碼中使用以下四個註解,而且這些註解所在的包名是上面配置的包及其子包,那麼spring會幫咱們把相應的bean加如到IOC容器中。spring

  • @Controller
  • @Service
  • @Repository
  • @Component

在註解的方式下如何實現呢?在咱們的配置類的上面加上以下註解便可
maven

@ComponentScan(value={"包名1","包名2"})

此時該註解指定的幾個包名及其子包中若是有類被上面四個註解修飾,那麼就會自動被注入到IOC容器中。 ide

注意:若是ComponentScan沒有其它配置的化,默認掃描與其配置類相同的包。 測試

一、實戰


新建一個maven工程,添加以下依賴ui

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>

一、BookControllerspa

package com.yefengyu.annotation.controller;

import org.springframework.stereotype.Controller;


@Controller
public class BookController
{
}

二、BookService ssr

package com.yefengyu.annotation.service;

import org.springframework.stereotype.Service;


@Service
public class BookService
{
}

三、BookRepository code

package com.yefengyu.annotation.repository;

import org.springframework.stereotype.Repository;


@Repository
public class BookRepository
{
}

四、主配置類component

package com.yefengyu.annotation.config;

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


@Configuration
@ComponentScan(value = "com.yefengyu.annotation")
public class MainConfig
{
}

五、測試

public static void main(String[] args)
{
    ApplicationContext ctx= new AnnotationConfigApplicationContext(MainConfig.class);
    String[] names = ctx.getBeanDefinitionNames();
    for (String name : names)
    {
        System.out.println(name);
    }
}

六、結果

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController
bookRepository
bookService

結果打印出如上內容,說明上面三個註解的bean都被添加到容器中。

二、規則過濾


@ComponentScan除了value 屬性以外,還有其餘屬性,其中比較經常使用的是以下兩個:

  • excludeFilters :排除哪些規則
  • includeFilters :指定哪些規則

他們的做用就是指定過濾規則。

一、指定規則

對於上面的代碼,只須要修改主配置類中ComponentScan註解中的內容便可:

@ComponentScan(value = "com.yefengyu.annotation", includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class)},useDefaultFilters = false)

上面的註解的含義是在com.yefengyu.annotation及其子包下面,將註解爲Service的bean加入到容器中。注意useDefaultFilters 默認爲true,表示使用默認的過濾規則:不過濾;若是須要指定規則,那麼就須要將useDefaultFilters 設置爲false。注意includeFilters 和useDefaultFilters 同時使用便可。

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookService

二、排除規則

對於上面的代碼,只須要修改主配置類中ComponentScan註解中的內容便可:

@ComponentScan(value = "com.yefengyu.annotation", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class)})

若是要排除某些規則,就要使用excludeFilters ,注意不須要使用useDefaultFilters ,默認便可。

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookController bookRepository

上面註解的含義就是在com.yefengyu.annotation及其子包下面,將註解爲Controller的bean排除容器以外。

三、FilterType的類型

  • ANNOTATION:註解,經常使用
  • ASSIGNABLE_TYPE:給定類型,該類型及其子類、接口的實現類都起做用
  • ASPECTJ
  • REGEX:正則
  • CUSTOM:自定義

自定義類型的使用方式:

package com.yefengyu.annotation;

import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;


public class MyTypeFilter implements TypeFilter
{
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
        throws IOException
    {
        //獲取當前類註解信息
         AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        //獲取當前掃描的類的信息
         ClassMetadata classMetadata = metadataReader.getClassMetadata();
        //獲取當前掃描類資源信息
         Resource resource = metadataReader.getResource();

        String className = classMetadata.getClassName();
        if (className.contains("er"))
        {
            return true;
        }
        return false;
    }
}

實現TypeFilter接口,重寫match方法,知足條件的則返回true.

而後指定掃描策略:

@ComponentScan(value = "com.yefengyu.annotation", excludeFilters = {@ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)})

結果以下:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig
bookRepository

將類中含有er的排除在外。

四、指定多個ComponentScan

一、在jdk8之後能夠直接寫多個ComponentScan

@ComponentScan(basePackages = "com.yefengyu.annotation1")
@ComponentScan(basePackages = "com.yefengyu.annotation2")

二、也可使用ComponentScans註解

@ComponentScans(value = {
    @ComponentScan(basePackages = "com.yefengyu.annotation1"),
    @ComponentScan(basePackages = "com.yefengyu.annotation2")
})
相關文章
相關標籤/搜索