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);
}
}
- 配置文件使用
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>
- 测试
@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 注解开发
- 配置类中使用
@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 {
}
- 测试
@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,不会注入到容器中
- 修改刚刚配置类,排除掉@Service注解,@Service注解标注的类不会注入到容器中
@Configuration
@ComponentScan(value = {"study.wyy.spring.anno.learn"},
excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Service.class})
}
)
public class MainConfig {
}
- 测试: 容器中不会存在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
- 只扫描符合规则的组件,默认的规则是是扫描全部
- 修改配置类,只扫描@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
- 实现
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;
}
}
- 配置类: 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 {
}
- 测试
@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);
}