反射
大约 1 分钟languagejava
反射
根据方法名称调用方法
package test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception {
Student stu = new Student();
stu.setAge(1);
stu.setName("lin");
//1.无参
Method method = stu.getClass().getMethod("getName");
String name = (String) method.invoke(stu);
//2.一个参数,后面的 Class.forName("java.lang.String") 表示参数是字符串类型
Method method2 = stu.getClass().getMethod("setName",Class.forName("java.lang.String"));
method2.invoke(stu, "meng");
//3.多参
Method method3 = stu.getClass().getMethod("method1",int.class,Class.forName("java.lang.String"));//后两个参数获得的都是class对象
method3.invoke(stu,15, "zhang");
}
}
判断类使用了指定的注解
if(clazz.isAnnotationPresent(ComponentScan.class)){
//TODO: 当某类实现了某个接口时要执行的逻辑
}
判断对象实现某接口
if(obj instanceof ComponentScan){
//TODO: xxx
}
遍历源码文件
其实是遍历编译后的 class 文件在手写 spring (项目 summer - https://gitee.com/chanchaw/summer.git)时写了遍历项目文件的注解 ComponentScan ,根据设置的包路径扫描并创建 bean 容器,关键代码如下:
// 类 configClass 使用了注解 @ComponentScan(自定义模拟 spring 的)
if(configClass.isAnnotationPresent(ComponentScan.class)){
ComponentScan annotation = (ComponentScan)configClass.getAnnotation(ComponentScan.class);
String beanPackage = annotation.value();// 拿到包路径:com.chanchaw.service
System.out.println("配置类设置了包路径:" + beanPackage);
// 包路径转换为文件夹路径
// com.chanchaw.service = com/chanchaw/service
String path = beanPackage.replace(".","/");
// 通过 ClassLoader 获取文件 - 编译后的
ClassLoader classLoader = SummerApplicationContext.class.getClassLoader();
URL resource = classLoader.getResource(path);
// 遍历指定目录下的所有文件
File file = new File(resource.getFile());
if(file.isDirectory())
for (File f : file.listFiles()) {
// 编译后 class 文件的完整路径:D:\software\summer\target\classes\com\chanchaw\service\OrderService.class
String absolutePath = f.getAbsolutePath();
// 将上面的文件完整路径转换为包路径+类名称:com.chanchaw.service.OrderService
String packageAndClass = getPackagePath(absolutePath);
try {
Class<?> clazz = classLoader.loadClass(packageAndClass);
// 使用了注解 @Component,并且没有设置 @Scope("prototype")
// 则在容器中创建实例对象
if(clazz.isAnnotationPresent(Component.class)){
BeanDefinition beanDefinition = getBeanDefinition(clazz);
beanDefinitionMap.put(beanDefinition.getDefaultBeanName(),beanDefinition);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
