Java手写实现spring中Ioc功能
1.环境搭建
1.1 搭建基础的环境
首先在idea上创建一个Maven项目。并引入相关依赖,
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<!-- junit测试-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.20.0</version>
</dependency>
然后再创建包,我这里创建了四个包,分别是anno,bean,dao和service,其中anno包下面创建了两个注解,分别为@Bean和@Di,其中@Bean是用于创建对象,@Di用于注入属性,我的包结构如下图:
1 @Bean
package com.yang.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//用于创建对象
@Target(ElementType.TYPE)//运用在类上面
@Retention(RetentionPolicy.RUNTIME)//运行时生效
public @interface Bean {
}
2 @Di
package com.yang.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//用于注入属性
@Target(ElementType.FIELD)//在属性上生效
@Retention(RetentionPolicy.RUNTIME)//在运行时生效
public @interface Di {
}
2.实现创建对象@Bean功能
在bean包下创建一个 ApplicationContext 接口和其实现类 AnnotationApplicationContext
package com.yang.bean;
public interface ApplicationContext {
Object getBean(Class clazz);
}
我们最终想要的效果是
ApplicationContext context = new AnnotationApplicationContext("com.yang");
输入com.yang…来获取context,所以我们要通过这个来获取这个包的全路径。
创建这个对象大致步骤是以下几步:
1.将com.yang里面的.替换成\
2.获取包的绝对路径,这个通过线程里面的方法来实现
3.然后实现包的扫描
4.判断是否为文件夹
5.如果为文件夹,那就获取文件夹里面的说有内容
6.如果文件夹为空,直接返回
7.如果文件夹不为空,那么就进行遍历,如果遍历到又是文件夹那就递归出去遍历
8.如果不是文件夹是文件,那么就要去获取包路径+类名称部分(实际上就是字符串的截取过程),获取到了这个路径我们才能通过反射的方式实现实例化
9.或得到了这个路径,将里面的.替换成\然后将.class去除掉
10.然后判断它是否为接口,如果不是接口判断这个文件上面有没有@Bean注解
11.如果有这个注解那么就实例化这个对象,然后将获得的对象存到map集合里面去
实现类代码
package com.yang.bean;
import com.yang.anno.Bean;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
public class AnnotationApplicationContext implements ApplicationContext{
//创建Map集合,放bean对象
private Map<Class,Object> beanFactory = new HashMap<>();
private