在日常开发的过程中,有可能需要自定义导入一些bean,有可能是按照自定义的包进行扫描,将bean导入到IOC容器中。
package com.edu.spring5;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.StringUtils;
import java.util.*;
public class CustomImportSelector implements ImportSelector {
/**
* 表达式:aspectj表达式
*/
private String expression;
private String customPackage;
public CustomImportSelector() {
try {
Properties properties = PropertiesLoaderUtils.loadAllProperties("custom.properties");
expression = properties.getProperty("custom.import.selector.expression");
customPackage = properties.getProperty("custom.import.selector.package");
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 实现要导入类的字节码
* 需求:
* 要导入的过滤规则typefilter采用aspectj方式
* @param importingClassMetadata
* @return
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
/**
* 定义扫描包的名称
*/
List<String> basePackages = null;
/**
* 获取@Import注解上是否有@ComponentScan注解
*/
if (importingClassMetadata.hasAnnotatedMethods(ComponentScan.class.getName())){
/**
* 取出componentscan的值
*/
Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
basePackages = new ArrayList<>(Arrays.asList((String[]) annotationAttributes.get("basePackages")));
if (basePackages == null || basePackages.size() == 0){
String basePackage = null;
try {
basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
/**
* 将包放入到basePackages中
*/
basePackages = new ArrayList<>();
basePackages.add(basePackage);
}
}
if (!StringUtils.isEmpty(customPackage)){
basePackages.add(customPackage);
}
/**
* 创建类路径扫描器,参数的含义,表明不使用默认过滤规则
*/
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
/**
* 创建类型过滤器
*/
TypeFilter typeFilter = new AspectJTypeFilter(expression,CustomImportSelector.class.getClassLoader());
/**
* 将类型过滤器添加到扫描器中
*/
scanner.addIncludeFilter(typeFilter);
final Set<java.lang.String> classes = new HashSet<>();
for (String basePackage:basePackages){
scanner.findCandidateComponents(basePackage).forEach(beanDefinition->{
classes.add(beanDefinition.getBeanClassName());
});
}
return classes.toArray(new String[classes.size()]);
}
}
这个样例,需要添加依赖:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
网友评论