<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.xiong"/>
beans>
package com.xiong.config;
import com.xiong.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MainConfig {
@Bean("human")
Person person() {
Person person = new Person();
person.setName("person");
person.setAge(20);
return person;
}
}
package com.xiong;
import com.xiong.bean.Person;
import com.xiong.config.MainConfig;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainTest {
@Test
public void getBeanByXmlFileTest() {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
System.out.println(person);
}
}
package com.xiong;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value = "com.xiong")
public class SpringApplicationMain {
}
package com.xiong.config;
import com.xiong.bean.Person;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MainConfig {
@Bean
Person person() {
Person person = new Person();
person.setName("person");
person.setAge(20);
return person;
}
}
public class MainTest {
@Test
public void getBeanByConfigClassTest() {
ApplicationContext context = new AnnotationConfigApplicationContext(SpringApplicationMain.class);
Person person = context.getBean("person", Person.class);
System.out.println(person);
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
包扫描的位置
指定只包含哪些组件
只包含哪些注解需要禁用默认的包扫描规则才能够生效
package com.xiong;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
@Configuration
@ComponentScan(value = "com.xiong",
includeFilters = {
@ComponentScan.Filter(
//指定注解方式过滤
type = FilterType.ANNOTATION,
//指定需要扫描的具体类型
classes = {Controller.class, Service.class}
)
},
useDefaultFilters = false)
public class SpringApplicationMain {
}
指定需要排除的组件
ANNOTATION
: 按照注解ASPECTJ
: 使用aspectj表达式ASSIGNABLE_TYPE
: 按照给定的class的类型CUSTOM
: 自定义规则REGEX
: 使用正则表达式package com.xiong;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
@Configuration
@ComponentScan(value = "com.xiong",
excludeFilters = {
@ComponentScan.Filter(
//指定注解方式过滤
type = FilterType.ANNOTATION,
//指定过滤的具体类型
classes = {Controller.class, Service.class}
)
})
public class SpringApplicationMain {
}
使用FilterType.CUSTOM时自定义过滤器
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,
/**
* 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
}
package com.xiong.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 org.springframework.core.type.filter.TypeFilter;
import java.io.IOException;
import java.util.Locale;
public class XTypeFilter implements TypeFilter {
/**
* @param metadataReader 读取到的当前正在扫描的类的信息
* @param metadataReaderFactory 可以获取到其他任何类的信息
* @return 如果成功匹配, 返回true; 否则返回false
* @throws IOException
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
//获取当前类注解信息
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//获取当前正在扫描的类的类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata();
//获取正在扫描的类的类名
String className = classMetadata.getClassName().toLowerCase(Locale.ROOT);
System.out.println(className);
//获取当前类资源(类路径classpath)
Resource resource = metadataReader.getResource();
// 如果扫描的类的类名中包含service(不考虑大小写的情况下), 返回true; 否则返回false
return className.contains("service");
}
}
package com.xiong;
import com.xiong.filter.XTypeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
@ComponentScan(value = "com.xiong",
excludeFilters = {
@ComponentScan.Filter(
//指定注解方式过滤
type = FilterType.CUSTOM,
//使用自定义的包扫描规则
classes = {XTypeFilter.class}
)
})
public class SpringApplicationMain {
}
todo
todo