通过类加载器得到的资源有个获取File的方法,然后我们通过File file = new File(resource.getFile());将资源转成File类型,因为他可以表示一个地址或者是具体文件 。扫描就是扫描文件路径,也就是文件夹 。我们可以打印看一下这个地址:
文章插图
判断是否为文件夹,如果是,那就获取里面的所有文件,在通过遍历这些文件,获取绝对路径 。
if (file.isDirectory()) { // 如果是文件夹 File[] files = file.listFiles(); for (File f : files) { String absolutePath = f.getAbsolutePath(); // 获取绝对路径 System.out.println("绝对路径:" + absolutePath); }}我们可以打印出来看一下:
因为我们要的是编译的.class文件,因此需要在遍历文件的时候进行判断文件是否为.class文件 。为了拿到这个类,需要通过全限定名使用类加载器获取类 , 也就是利用反射机制 。我们都知道,spring是通过Component注解来将bean注入spring的,因此最后就是通过判断是否有这个注解来得到一个bean 。
for (File f : files) { String absolutePath = f.getAbsolutePath(); // 获取绝对路径 System.out.println("绝对路径:" + absolutePath); // 1.5 对编译文件进行处理 if (absolutePath.endsWith(".class")) { // 判断是否为编译文件/** * 需要拿到的是编译文件,通过类加载器去获取 * 需要将com\lyd\service\UserService转成com.lyd.service.UserService */String className = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));className = className.replace("\\", ".");System.out.println("类名:" + className);try {// 1.6 通过全限定名使用类加载器获取类 (利用反射机制)Class<?> clazz = classLoader.loadClass(className);// 1.7 在通过这个clazz(类)来判断是否有component注解,有则是beanif (clazz.isAnnotationPresent(Component.class)) {// 到这里就是一个bean}} catch (Exception e) {e.printStackTrace();} }}最后我们需要的地址就是如下:
Spring生成BeanDefinition在我们Spring容器启动或者是扫描的时候,并不建议直接实例化bean对象,因为bean是区分单例和多例的,多例bean我们是需要用到的时候再去创建 。这个时候就需要生成BeanDefinition,即bean的定义 , 这个类存储了类和作用域(单例还是多例) 。
定义Scope注解通过Scope这个注解来标明是单例bean还是多例bean 。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Scope { String value() default "";}定义BeanDefinition在spring中,不会在获取bean的时候再去解析是否为单例,而是通过BeanDefinition类来操作 。对bean的定义,记录了bean类和作用域 。
public class BeanDefinition { private Class type; private String scope; // 单例多例 public Class getType() { return type; } public void setType(Class type) { this.type = type; } public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; }}因为我们注入spring的bean对象是有Component注解,因此在扫描的时候 , 我们会通过这个获得到bean , 在这时候去创建BeanDefinition对象 。通过判断注解上的值来赋值其作用域 , 如果没有设置,就默认是单例模式 。创建好的bean对象 , 我们还需要将他进行保存起来,这个就需要定义ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();存储beanDefinition 。key是component的值,如果component没有传入beanName的值,那就使用spring的命名规则,采用类名首字母小写 。
推荐阅读
- 【ASP.NET Core】MVC控制器的各种自定义:应用程序约定的接口与模型
- 基础版 【网络】内网穿透方案&FRP内网穿透实战
- FGO日服七周年礼装自选哪个好
- 蚂蚁庄园今日答题答案是什么
- iqooneo5是什么屏幕_iqooneo5屏幕尺寸参数
- 原神如何去雷神的岛屿(原神如何上雷神岛)
- 一次SpringBoot版本升级,引发的血案
- 中 学习ASP.NET Core Blazor编程系列十——路由
- 小米11和vivox60哪个好_小米11和vivox60参数对比
- 苹果13mini屏幕多大尺寸_苹果13mini屏幕尺寸