spring注解開發:ComponentScan組件掃描


在使用xml方式配置時,我們只需要在xml中配置如下代碼:

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

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

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

在注解的方式下如何實現呢?在我們的配置類的上面加上如下注解即可

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

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

注意:如果ComponentScan沒有其它配置的化,默認掃描與其配置類相同的包。

1、實戰


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

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

1、BookController

package com.yefengyu.annotation.controller;

import org.springframework.stereotype.Controller;


@Controller
public class BookController
{
}

2、BookService

package com.yefengyu.annotation.service;

import org.springframework.stereotype.Service;


@Service
public class BookService
{
}

3、BookRepository

package com.yefengyu.annotation.repository;

import org.springframework.stereotype.Repository;


@Repository
public class BookRepository
{
}

4、主配置類

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
{
}

5、測試

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

6、結果

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都被添加到容器中。

2、規則過濾


@ComponentScan除了value 屬性之外,還有其他屬性,其中比較常用的是如下兩個:

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

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

1、指定規則

對於上面的代碼,只需要修改主配置類中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

2、排除規則

對於上面的代碼,只需要修改主配置類中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排除容器之外。

3、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的排除在外。

4、指定多個ComponentScan

1、在jdk8以后可以直接寫多個ComponentScan

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

2、也可以使用ComponentScans注解

@ComponentScans(value = {
    @ComponentScan(basePackages = "com.yefengyu.annotation1"),
    @ComponentScan(basePackages = "com.yefengyu.annotation2")
})


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM