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 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 getAllClassName(File dir) {

List 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 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 objectMap = new HashMap<>();

/**

* 初始化方法

* @param packageName

*/

public static void init(String packageName) {

try {

//1 扫描 指定包 下面的所有内容(接口、类)

// 1.1 获得 指定包 所在的位置,以文件File形式

File packageFile = packageToFile(packageName);

// 1.2 根据 包的位置 获得所有的类

List 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,创建controller

boolean 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 getAllClassName(File dir) {

List 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 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;

}

@Override

public 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 objectMap = new HashMap<>();

/**

* 初始化方法

* @param packageName

*/

public static void init(String packageName) {

try {

//1 扫描 指定包 下面的所有内容(接口、类)

// 1.1 获得 指定包 所在的位置,以文件File形式

File packageFile = packageToFile(packageName);

// 1.2 根据 包的位置 获得所有的类

List 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,创建controller

boolean 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 变量ObjectMap

for(Map.Entry entry : objectMap.entrySet()) {

// 获得map中对象对应的Class

Class beanClass = entry.getValue().getClass();

// 2.2 获得所有的字段(含私有)

Field[] fieldList = beanClass.getDeclaredFields();

// 2.3 遍历字段

for(Field field: fieldList) {

// 2.4 判断字段是否有@Resource

boolean 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 getAllClassName(File dir) {

List 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 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;

}

}

}

相关链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。