JavaEE-自定义SSM-编写核心- my spring bean工厂(IoC、DI)

3.4 my spring bean工厂(IoC、DI)

  • 加载类
  • 解析类
  • 获得类

3.4.0 分析

在这里插入图片描述
3.4.1 扫描指定包下的所有类
在这里插入图片描述

package com.czxy.bean;import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;public class MyBeanFactory {private static String classpath = new File(MyBeanFactory.class.getClassLoader().getResource("").getPath()).getPath();/*** 初始化方法* @param packageName*/public static void init(String packageName) {//1 扫描 指定包 下面的所有内容(接口、类)// 1.1 获得 指定包 所在的位置,以文件File形式File packageFile = packageToFile(packageName);// 1.2 根据 包的位置 获得所有的类List<String> classNameList = getAllClassName(packageFile);System.out.println(classNameList);//2 处理类}/*** com.czxy --> com/czxy* @param packageName* @return*/private static File packageToFile(String packageName) {return new File(classpath , packageName.replace(".", "/"));}/*** 获得指定包所有内容,如果是类* @param dir* @return*/private static List<String> getAllClassName(File dir) {List<String> list = new ArrayList<>();if(dir == null) {return list;}for(File file: Objects.requireNonNull(dir.listFiles())) {if(file.isFile()) {list.add(pathToClassName(file.getPath()));} else {List<String> subList = getAllClassName(file);list.addAll(subList);}}return list;}/**** @param path* @return A.B.C*/private static String pathToClassName(String path) {// 取消前缀String newPath = path.replace(classpath + "\\", "");if(newPath.endsWith(".class")) {//处理类String tempPath = newPath.replace("\\", ".");return tempPath.substring(0, tempPath.length() - 6);} else {return newPath;}}
}

在程序运行时,执行bean工厂初始化
在这里插入图片描述
3.4.2 创建bean实例(IoC)
在这里插入图片描述
Bean工厂

在这里插入图片描述
*

package com.czxy.bean;import com.czxy.annotation.MyMapper;
import com.czxy.annotation.MyRestController;
import com.czxy.annotation.MyService;
import com.czxy.boot.MybatisHandler;import java.io.File;
import java.lang.reflect.Proxy;
import java.util.*;public class MyBeanFactory {private static String classpath = new File(MyBeanFactory.class.getClassLoader().getResource("").getPath()).getPath();private static Map<Class, Object> objectMap = new HashMap<>();/*** 初始化方法* @param packageName*/public static void init(String packageName) {try {//1 扫描 指定包 下面的所有内容(接口、类)// 1.1 获得 指定包 所在的位置,以文件File形式File packageFile = packageToFile(packageName);// 1.2 根据 包的位置 获得所有的类List<String> classNameList = getAllClassName(packageFile);//2 处理类:创建实例(IoC)// 2.1 遍历所有的类文件for(String className: classNameList) {// 2.2 获得类对应Class对象Class beanClass = Class.forName(className);// 2.3 根据注解创建实例// 2.3.1 如果有@RestController,创建controllerboolean isController = beanClass.isAnnotationPresent(MyRestController.class);if(isController) {// 直接创建对象objectMap.put(beanClass, beanClass.newInstance());}// 2.3.2 如果有@Service,创建Service,需要获得接口boolean isService = beanClass.isAnnotationPresent(MyService.class);if(isService) {// 如果有接口,接口-->实现类。 如果没有接口, 实现类-->实现类Class[] interfaces = beanClass.getInterfaces();if(interfaces.length == 0) {// 没有接口objectMap.put(beanClass, beanClass.newInstance());} else {// 有接口objectMap.put(interfaces[0], beanClass.newInstance());}}// 2.3.3 如果有@Mapper,创建代理boolean isMapper = beanClass.isAnnotationPresent(MyMapper.class);if(isMapper) {// 创建Map对应的代理类// 1) 参数// 1.1) 类加载器ClassLoader loader = MyBeanFactory.class.getClassLoader();// 1.2) 接口们Class[] interfaces = new Class[] {beanClass};// 1.3) 处理类MybatisHandler mybatisHandler = new MybatisHandler(beanClass);// 2) 工具创建objectMap.put(beanClass, Proxy.newProxyInstance(loader, interfaces, mybatisHandler));}}} catch (Exception e) {throw new RuntimeException(e);}System.out.println(objectMap);}/*** com.czxy --> com/czxy* @param packageName* @return*/private static File packageToFile(String packageName) {return new File(classpath , packageName.replace(".", "/"));}/*** 获得指定包所有内容,如果是类* @param dir* @return*/private static List<String> getAllClassName(File dir) {List<String> list = new ArrayList<>();if(dir == null) {return list;}for(File file: Objects.requireNonNull(dir.listFiles())) {if(file.isFile()) {list.add(pathToClassName(file.getPath()));} else {List<String> subList = getAllClassName(file);list.addAll(subList);}}return list;}/**** @param path* @return A.B.C*/private static String pathToClassName(String path) {// 取消前缀String newPath = path.replace(classpath + "\\", "");if(newPath.endsWith(".class")) {//处理类String tempPath = newPath.replace("\\", ".");return tempPath.substring(0, tempPath.length() - 6);} else {return newPath;}}
}
  • 代理类处理类

    package com.czxy.boot;import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;public class MybatisHandler implements InvocationHandler {private Class beanClass;public MybatisHandler(Class beanClass) {this.beanClass = beanClass;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("代理类的处理类执行了");//1 获得方法名String methodName = method.getName();//2 处理 toString 方法if("toString".equals(methodName)) {return "myProxy";}return null;}
    }

3.4.3 依赖关系

在这里插入图片描述
package com.czxy.bean;

import com.czxy.annotation.MyMapper;
import com.czxy.annotation.MyRestController;
import com.czxy.annotation.MyService;
import com.czxy.boot.MybatisHandler;

import javax.annotation.Resource;
import javax.annotation.Resources;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.util.*;

public class MyBeanFactory {

private static String classpath = new File(MyBeanFactory.class.getClassLoader().getResource("").getPath()).getPath();private static Map<Class, Object> objectMap = new HashMap<>();/*** 初始化方法* @param packageName*/
public static void init(String packageName) {try {//1 扫描 指定包 下面的所有内容(接口、类)// 1.1 获得 指定包 所在的位置,以文件File形式File packageFile = packageToFile(packageName);// 1.2 根据 包的位置 获得所有的类List<String> classNameList = getAllClassName(packageFile);//2 处理类:创建实例(IoC)// 2.1 遍历所有的类文件for(String className: classNameList) {// 2.2 获得类对应Class对象Class beanClass = Class.forName(className);// 2.3 根据注解创建实例// 2.3.1 如果有@RestController,创建controllerboolean isController = beanClass.isAnnotationPresent(MyRestController.class);if(isController) {// 直接创建对象objectMap.put(beanClass, beanClass.newInstance());}// 2.3.2 如果有@Service,创建Service,需要获得接口boolean isService = beanClass.isAnnotationPresent(MyService.class);if(isService) {// 如果有接口,接口-->实现类。 如果没有接口, 实现类-->实现类Class[] interfaces = beanClass.getInterfaces();if(interfaces.length == 0) {// 没有接口objectMap.put(beanClass, beanClass.newInstance());} else {// 有接口objectMap.put(interfaces[0], beanClass.newInstance());}}// 2.3.3 如果有@Mapper,创建代理boolean isMapper = beanClass.isAnnotationPresent(MyMapper.class);if(isMapper) {// 创建Map对应的代理类// 1) 参数// 1.1) 类加载器ClassLoader loader = MyBeanFactory.class.getClassLoader();// 1.2) 接口们Class[] interfaces = new Class[] {beanClass};// 1.3) 处理类MybatisHandler mybatisHandler = new MybatisHandler(beanClass);// 2) 工具创建objectMap.put(beanClass, Proxy.newProxyInstance(loader, interfaces, mybatisHandler));}}//3 处理类:依赖注入// 2.1 变量ObjectMapfor(Map.Entry<Class, Object> entry : objectMap.entrySet()) {// 获得map中对象对应的ClassClass beanClass = entry.getValue().getClass();// 2.2 获得所有的字段(含私有)Field[] fieldList = beanClass.getDeclaredFields();// 2.3 遍历字段for(Field field: fieldList) {// 2.4 判断字段是否有@Resourceboolean isResource = field.isAnnotationPresent(Resource.class);if(isResource) {// 2.5 如果有注解,获得类型Class<?> fieldType = field.getType();// 2.6 根据类型,从objectMap获得对应的对象Object obj = objectMap.get(fieldType);// 2.7 设置访问权限field.setAccessible(true);// 2.8 设置对象field.set(entry.getValue(), obj);}}}} catch (Exception e) {throw new RuntimeException(e);}System.out.println(objectMap);
}/*** com.czxy --> com/czxy* @param packageName* @return*/
private static File packageToFile(String packageName) {return new File(classpath , packageName.replace(".", "/"));
}/*** 获得指定包所有内容,如果是类* @param dir* @return*/
private static List<String> getAllClassName(File dir) {List<String> list = new ArrayList<>();if(dir == null) {return list;}for(File file: Objects.requireNonNull(dir.listFiles())) {if(file.isFile()) {list.add(pathToClassName(file.getPath()));} else {List<String> subList = getAllClassName(file);list.addAll(subList);}}return list;
}/**** @param path* @return A.B.C*/
private static String pathToClassName(String path) {// 取消前缀String newPath = path.replace(classpath + "\\", "");if(newPath.endsWith(".class")) {//处理类String tempPath = newPath.replace("\\", ".");return tempPath.substring(0, tempPath.length() - 6);} else {return newPath;}
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/435016.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【GitHub项目推荐--十六进制编辑器】【转载】

一款名为 ImHex 的十六进制编辑器获得了 15.3k 的 Star。十六进制编辑器可以让你以十六进制的形式查看或编辑文件的二进制数据&#xff0c;并用较为友好的界面来编辑二进制数据&#xff0c;和常见的十六进制编辑器 GNOME Hex Editor 等不一样&#xff0c;ImHex 功能非常强大&am…

C语言 小明喝饮料

题目&#xff1a;喝汽水&#xff0c;1瓶汽水1元&#xff0c;2个空瓶可以换汽水&#xff0c;给n元&#xff0c;可以喝多少汽水//理论问题&#xff0c;请勿模仿-^- #include <stdio.h> int main() {int n,ret,i;scanf("%d", &n);ret n;while (n>1){ret …

时间编程相关的API

1》time -- 获取日历时间 日历时间&#xff1a;1970年1月1日距离现在的秒数 #include <time.h> time_t time(time_t *timer): 获取当前的系统时间&#xff0c;并以time_t类型返回。 2》将日历时间转化为本地时间 localtime #include <time.h> struct tm *localtim…

文件包含技术总结

开发人员一般会把重复使用的函数写到单个文件中&#xff0c;需要使用某个函数时直接调用此文件&#xff0c;而无需再次编写&#xff0c;这中文件调用的过程一般被称为文件包含。 allow_url_fopen On&#xff08;是否允许打开远程文件&#xff09; allow_url_include On&…

计算机中丢失mfc100u.dll怎么解决,详细解析mfc100u.dll丢失的解决方法

遭遇“无法找到mfc100u.dll”的错误不必过分担忧&#xff0c;这是一个普遍现象。许多用户在启动某些软件或游戏的时候可能会碰到这样的情况。通常&#xff0c;这个错误信息表明你的计算机系统中缺失了一个关键的动态链接库(DLL)文件&#xff0c;它可能会妨碍应用程序的顺利启动…

Linux 驱动开发基础知识—— 具体单板的 LED 驱动程序(五)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

《HelloGitHub》第 94 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …

推荐一款第三方的日历框架------CalendarView

简介 Android上一个优雅、高度自定义、性能高效的日历控件&#xff0c;完美支持周视图&#xff0c;支持标记、自定义颜色、农历等&#xff0c;任意控制月视图显示、任意日期拦截条件、自定义周起始等。Canvas绘制&#xff0c;极速性能、占用内存低&#xff0c;支持简单定制即可…

STL容器大总结区分(上)

如图所示 ,按大小说明其重要性 那就先说两个最重要的: vector---数组 list-----链表 vector 基本概念 功能&#xff1a; vector 数据结构和 数组非常 相似 &#xff0c;也称为 单端数组 vector 与普通数组区别&#xff1a; 不同之处在于数组是静态空间&…

HarmonyOS漫谈---套壳安卓还是套壳苹果?HarmonyOS更像谁?

2020年以前华为手机的操作系统是EMUI,这个是在Android基础上扩展而来的,版本和android几乎一致,和市面上其它android手机厂家搭载的系统并无本质不同 2019年5月16日,美国针对华为发起了第一轮制裁。8月华为发布了HarmonyOS1.0,此时还只是主要在IOT设备上使用,智慧屏成为…

贝叶斯增量式跨域适应:少样本 + 跨模态学习 + 知识保留和推断【fundus + OCT】,做视网膜病变

贝叶斯深度学习&#xff1a;增量式少样本学习跨域适应 贝叶斯多目标函数 跨模态学习 fundus OCT&#xff0c;做视网膜病变 核心思想设计网络&#xff1a;寻找分类模型、损失函数实验结果混淆矩阵与注意力图评估 总结 核心思想 论文&#xff1a;https://arxiv.org/pdf/2110.…

paddlepaddle在执行loss.item()的时候,报错an illegal memory access was encountered.

遇到的问题是“an illegal memory access was encountered”&#xff0c;这是一个常见的内存错误。 首先&#xff0c;要确保你的代码中没有其他明显的内存错误&#xff0c;例如&#xff1a; 确保你没有试图访问超出数组边界的元素。确保你没有试图释放已经释放的内存。确保你没…