自己写的spring整合mybatis,涉及到好多spring的知识,有助于我们理解spring框架,有助于我们在构思公司的框架的时候提供一些思路,所以有必要学习
1. 构建的enable注解
构建enable注解,通常和@Import注解一起使用
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MapperRegistrar.class)
public @interface EnableMapperScanner {
String[] value() default {};
}
2. 扫描启动器
public class MapperRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
List<String> pkgList = parsePkgList(annotationMetadata);
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.registerFilters();
scanner.doScan(StringUtils.toStringArray(pkgList));
}
private List<String> parsePkgList(AnnotationMetadata annotationMetadata) {
AnnotationAttributes annoAttrs =
AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(EnableMapperScanner.class.getName()));
String[] basePkgs = annoAttrs.getStringArray("value");
List<String> resultList = new ArrayList<>();
for (String pkg : basePkgs) {
if (StringUtils.isEmpty(pkg)) {
continue;
}
resultList.add(pkg);
}
return resultList;
}
}
3. 扫描器
扫到接口就
public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
private MapperFactoryBean mapperFactoryBean = new MapperFactoryBean();
public ClassPathMapperScanner(BeanDefinitionRegistry registry) {
super(registry);
}
public void registerFilters(){
addIncludeFilter(new TypeFilter() {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
return true;
}
});
}
@Override
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
if (beanDefinitions == null || beanDefinitions.isEmpty()) {
return beanDefinitions;
}
reProcessBeanDefinitions(beanDefinitions);
return beanDefinitions;
}
private void reProcessBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
for (BeanDefinitionHolder holder : beanDefinitions) {
GenericBeanDefinition beanDefinition = (GenericBeanDefinition)holder.getBeanDefinition();
beanDefinition.getConstructorArgumentValues()
.addGenericArgumentValue(beanDefinition.getBeanClassName());
beanDefinition.setBeanClass(mapperFactoryBean.getClass());
beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
}
}
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
return metadata.isInterface();
}
}
4. 代理器
public class MapperProxy implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Map<String, Object> respMap = new HashMap<>();
respMap.put("name", "roy");
respMap.put("args", args);
respMap.put("age", "18");
return respMap;
}
}
5. FactoryBean 实例
public class MapperFactoryBean<T> implements FactoryBean<T> {
private Class<T> rawMapperClass;
public MapperFactoryBean() {
}
public MapperFactoryBean(Class<T> rawMapperClass) {
this.rawMapperClass = rawMapperClass;
}
@Override
public T getObject() throws Exception {
Object proxy = Proxy.newProxyInstance(
rawMapperClass.getClassLoader(),
new Class[]{rawMapperClass},
new MapperProxy()
);
return (T) proxy;
}
@Override
public Class<?> getObjectType() {
return rawMapperClass;
}
}
6. test
@RestController
public class ScannerController {
@Autowired
private UserMapper userMapper;
@RequestMapping("/user")
public Object getUserById(String userId){
return userMapper.getUserById(userId);
}
}
启动类
@SpringBootApplication
@EnableAspectJAutoProxy
@PropertySource(encoding = "UTF-8",
ignoreResourceNotFound = true,
value = {"file:/tmp/roy.properties"})
@EnableMapperScanner(value = {"com.roy.scanner.mapper"})
public class APP {
public static void main(String[] args) {
SpringApplication.run(APP.class, args);
}
}