02 sping注解开发-@ComponenScan

1 配置文件

  1. 一个UserService组件
package study.wyy.spring.anno.learn.service;

import org.springframework.stereotype.Service;
import study.wyy.spring.anno.learn.model.Person;

/**
 * @author :wyaoyao
 * @date : 2020-06-13 14:43
 */
@Service
public class UserService {

    public Person findPerson(){
        return new Person("Wade", 12);
    }
}
  1. 配置文件使用component-scan扫描到该组件
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans" 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.xsd">
    <context:component-scan base-package="study.wyy.spring.anno.learn"></context:component-scan>
</beans>
  1. 测试
@Test
public void testXml() {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
    for (String beanName : beanDefinitionNames) {
        log.info("ioc 容器中定义的bean: {}", beanName);
    }
    UserService bean = applicationContext.getBean(UserService.class);
    Person person = bean.findPerson();
    // 使用class
    Assert.assertThat(person.getName(), equalTo("Wade"));
    Assert.assertThat(person.getAge(), equalTo(12));
}

2 注解开发

  1. 配置类中使用@ComponenScan
package study.wyy.spring.anno.learn.config;

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

/**
 * @author :wyaoyao
 * @date : 2020-06-13 14:42
 * @ComponentScan : 配置包扫描
 *
 */
@Configuration
@ComponentScan({"study.wyy.spring.anno.learn"})
public class MainConfig {
}
  1. 测试
@Test
public void testAnno() {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
    String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
    for (String beanName : beanDefinitionNames) {
        log.info("ioc 容器中定义的bean: {}", beanName);
    }
    UserService bean = applicationContext.getBean(UserService.class);
    Person person = bean.findPerson();
    // 使用class
    Assert.assertThat(person.getName(), equalTo("Wade"));
    Assert.assertThat(person.getAge(), equalTo(12));
}

3 @ComponenScan的配置项

3.1 excludeFilters

  • 用于排除符合规则的bean,不会注入到容器中
  1. 修改刚刚配置类,排除掉@Service注解,@Service注解标注的类不会注入到容器中
@Configuration
@ComponentScan(value = {"study.wyy.spring.anno.learn"},
        excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class})
        }
)
public class MainConfig {


}
  1. 测试: 容器中不会存在UserService这个组件
 @Test(expected=NoSuchBeanDefinitionException.class)
    public void testExcludeFilters() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            log.info("ioc 容器中定义的bean: {}", beanName);
        }
        // 这里会抛出NoSuchBeanDefinitionException
        UserService userService = applicationContext.getBean(UserService.class);
    }

3.2 includeFilters

  • 只扫描符合规则的组件,默认的规则是是扫描全部
  1. 修改配置类,只扫描@Service注解,需要指定不使用默认的过滤规则
@Configuration
//@ComponentScan(value = {"study.wyy.spring.anno.learn"},
//        excludeFilters = {
//            @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class})
//        }
//)
@ComponentScan(value = {"study.wyy.spring.anno.learn"},
        includeFilters = {
                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class})
        }
,useDefaultFilters = false)
public class MainConfig {


}

2 测试

 /**
     * Person: 是通过BeanConfig这个配置类注入的,由于只会扫描@Service注解的组件
     * 故BeanCo这个类就没有生效,所以Person不存在
     */
    @Test(expected=NoSuchBeanDefinitionException.class)
    public void testIncludeFilters() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            log.info("ioc 容器中定义的bean: {}", beanName);
        }
        // 这里会抛出NoSuchBeanDefinitionException
        Person person = applicationContext.getBean(Person.class);
    }

3.3 FilterType

  • includeFilters和excludeFilters有个参数为FilterType(枚举),用于指定Fileter类型
public enum FilterType {

	/**
	 * Filter candidates marked with a given annotation.
	 * @see org.springframework.core.type.filter.AnnotationTypeFilter
	 * 注解类型
	 */
	ANNOTATION,

	/**
	 * Filter candidates assignable to a given type.
	 * @see org.springframework.core.type.filter.AssignableTypeFilter
	 * 指定的类型
	 */
	ASSIGNABLE_TYPE,

	/**
	 * Filter candidates matching a given AspectJ type pattern expression.
	 * @see org.springframework.core.type.filter.AspectJTypeFilter
	 * 按照Aspectj的表达式,基本上不会用到
	 */
	ASPECTJ,

	/**
	 * Filter candidates matching a given regex pattern.
	 * @see org.springframework.core.type.filter.RegexPatternTypeFilter
	 * 按照正则表达式
	 */
	REGEX,

	/** Filter candidates using a given custom
	 * {@link org.springframework.core.type.filter.TypeFilter} implementation.
	 * 自定义规则
	 */
	CUSTOM

}

eg: 排除UserService这个类型的

@Configuration
@ComponentScan(value = {"study.wyy.spring.anno.learn"},
        excludeFilters = {
            @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {UserService.class})
        }
)
//@ComponentScan(value = {"study.wyy.spring.anno.learn"},
//        includeFilters = {
//                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class})
//        }
//,useDefaultFilters = false)
public class MainConfig {


}

测试: 这里新增了一个AddressService组件

  @Test(expected=NoSuchBeanDefinitionException.class)
    public void testExcludeFilters2() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            log.info("ioc 容器中定义的bean: {}", beanName);
        }
        AddressService addressService = applicationContext.getBean(AddressService.class);
        Assert.assertThat(addressService,notNullValue());
        // 这里会抛出NoSuchBeanDefinitionException
        UserService userService = applicationContext.getBean(UserService.class);
    }
自定义过滤规则Demo
  1. 实现org.springframework.core.type.filter.TypeFilter接口
package study.wyy.spring.anno.learn.filter;

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 java.io.IOException;

/**
 * @author :wyaoyao
 * @date : 2020-06-13 17:02
 */
public class MyTypeFilter implements org.springframework.core.type.filter.TypeFilter {

    /**
     * 返回值为True表示匹配成功
     * @param metadataReader: 获取当前扫描到的类的信息
     * @param metadataReaderFactory: 可以获取到其他类的信息
     * @return
     * @throws IOException
     */
    @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();
        // 类名包含User,匹配成功
        if(className.contains("User")){
            return true;
        }

        return false;
    }
}

  1. 配置类: UserService会被匹配到,不会被扫描到
package study.wyy.spring.anno.learn.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import study.wyy.spring.anno.learn.filter.MyTypeFilter;

/**
 * @author :wyaoyao
 * @date : 2020-06-13 14:42
 * @ComponentScan : 配置包扫描
 *
 */
@Configuration
@ComponentScan(value = {"study.wyy.spring.anno.learn"},
        excludeFilters = {
            @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
        }
)
//@ComponentScan(value = {"study.wyy.spring.anno.learn"},
//        includeFilters = {
//                @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class})
//        }
//,useDefaultFilters = false)
public class MainConfig {


}
  1. 测试
@Test(expected=NoSuchBeanDefinitionException.class)
    public void testExcludeFilters3() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            log.info("ioc 容器中定义的bean: {}", beanName);
        }
        AddressService addressService = applicationContext.getBean(AddressService.class);
        Assert.assertThat(addressService,notNullValue());
        // 这里会抛出NoSuchBeanDefinitionException
        UserService userService = applicationContext.getBean(UserService.class);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值