此文章中会简单的模拟一下Spring的scan方法,Spring底层使用的更优的扫描算法,此处就以简单的文件操作完成
实现步骤:
- 自定义注解作为扫描的标识,作用就同@Component作用
- 在Spring中是利用给配置文件中添加@ComponentScan注解,此处就直接写出basePackage,原理和第一点相同
- 调用方法,并打印
代码:
自定义注解Wa.java
package anno;
/*
* @Author Wrial
* @Date Created in 21:10 2020/2/13
* @Description 自定义注解
*/
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
//生命周期为运行时
@Retention(RetentionPolicy.RUNTIME)
public @interface Wa {
public String value();
}
自定义service并使用自定义注解
package com.wrial.service;
/*
* @Author Wrial
* @Date Created in 21:31 2020/2/13
* @Description
*/
import anno.Wa;
@Wa("myService")
public class MyService {
}
自定义扫描器
步骤:
- 先获取当前工厂的类根路径
- 对传入的basePackage进行处理
- 对类根路径和basePackage进行拼接,并创建File对象
- 遍历File下对象并利用反射创建Class
- 判断是否有自定义注解,有就打印name和注解中定义的beanName
package org.spring.utils;
/*
* @Author Wrial
* @Date Created in 22:24 2020/2/12
* @Description 模拟注解版的
*/
import anno.Wa;
import java.io.File;
public class AnnotationConfigApplicationContext {
/**
* 容器扫描方法
*
* @param basePackage 包名
*/
public void scan(String basePackage) {
//得到类的根路径,作为ClassPath随生产环境而变
String rootClassPath = this.getClass().getResource("/").getPath();
//转换所有的点为 \\
String basePackagePath = basePackage.replaceAll("\\.", "\\\\");
File file = new File(rootClassPath + "//" + basePackagePath);
String[] names = file.list();
try {
for (String name : names) {
name = name.replaceAll(".class", "");
Class<?> clazz = Class.forName(basePackage + "." + name);
if (clazz.isAnnotationPresent(Wa.class)) {
Wa wa = clazz.getAnnotation(Wa.class);
System.out.println(wa.value());
System.out.println(clazz.newInstance());
}else {
System.out.println("没有要扫描的类");
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
测试类
public class TestAnnotationConfigApplicationContext {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
annotationConfigApplicationContext.scan("com.wrial.service");
}
}