gitee地址(需要自取)ioc_Imitation: 简单仿写IOC (gitee.com)
项目目录结构
Autowired
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
Component
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
}
HydService
@Component
public class HydService {
public void test() {
System.out.println("成功调用service方法");
}
}
HydIOC
public class HydIOC {
// 包名加类名(没有.java后缀)
private List<String> bean_names;
// 全类路径
private List<String> file_paths;
// main方法路径
private String base_path;
// 包名
private String base_package;
// 放类实例
private Map<String,Object> beans = new HashMap<>();
public HydIOC(String basepath, String basepackage) {
// 处理basepath和basepackage
// basepath:/D:/javacode/myIOC/out/production/myIOC/com/hyd/springIOC/
// 处理成:D:\javacode\myIOC\out\production\myIOC\com\hyd\springIOC\
basepath=basepath.substring(1).replace("/","\\");
this.base_path=basepath;
// 形如:com.hyd.springIOC
this.base_package=basepackage;
try{
// 扫描文件
scan_files();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 获取实例的名称集合
this.bean_names = new ArrayList<>();
init_bean_names();
}
/**
* 生成bean_names
*/
private void init_bean_names() {
for (String file_path : this.file_paths) {
file_path = file_path.replace(this.base_path,"");
if (file_path.endsWith(".class")){
file_path = file_path.substring(0,file_path.length()-6);
}
String bean_name = this.base_package + "." + file_path.replaceAll(Matcher.quoteReplacement(File.separator),".");
this.bean_names.add(bean_name);
}
}
/**
* 扫描当前路径下的文件
*/
private void scan_files() throws FileNotFoundException {
File file = new File(this.base_path);
this.file_paths = new ArrayList<>();
if (file.exists()){
// 新建一个用来处理文件的队列
LinkedList<File> file_lists = new LinkedList<>();
file_lists.add(file);
while (!file_lists.isEmpty()){
// 取出一个文件进行处理
File temp_file = file_lists.removeFirst();
if (temp_file!=null){
// 判断是否为文件夹
if (temp_file.isDirectory()){
// 是文件夹就把其子文件放到队列中
File[] files = temp_file.listFiles();
for (File file1 : files) {
file_lists.add(file1);
}
}else {
// 不是文件夹就把文件路径放到路径列表中
this.file_paths.add(temp_file.getPath());
}
}else {
continue;
}
}
}else {
throw new FileNotFoundException("找不到"+this.base_path+"路径下的文件");
}
}
public void initBeans() {
for (String bean_name : this.bean_names) {
try{
Class<?> cl = Class.forName(bean_name);
// 获取类的全部注解
Annotation[] annotations = cl.getDeclaredAnnotations();
// 判断所有注解汇中是否有Component注解
for (Annotation annotation : annotations) {
if (annotation instanceof Component){
// 有就把实例化对象放到map中
Object o = cl.newInstance();
this.beans.put(cl.getName(),o);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
// 处理Autowired注解的注入
// 遍历map所有的实例
for (Map.Entry<String, Object> entry : this.beans.entrySet()) {
// 获取实例中的域
Field[] fields = entry.getValue().getClass().getDeclaredFields();
// 遍历所有的域
for (Field field : fields) {
// 获取域的注解
Annotation[] annotations = field.getDeclaredAnnotations();
// 遍历注解
for (Annotation annotation : annotations) {
// 判断注解中是否有Autowired注解
if (annotation instanceof Autowired){
// filed样例值:private com.hyd.springIOC.service.HydService com.hyd.springIOC.controller.HydController.hydService
// name样例值:com.hyd.springIOC.service.HydService
String name = field.getType().getName();
// 从map中获取对应的实例
Object o = this.beans.get(name);
// 设置字段为可访问状态
field.setAccessible(true);
try {
// 将获取的对象实例 o 注入到当前字段所属的对象实例中
field.set(entry.getValue(),o);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
// 对外获取实例的方法
public Object getInstance(String name) {
return this.beans.get(name);
}
}
HydController
@Component
public class HydController {
@Autowired
private HydService hydService;
public void hydtest(){
hydService.test();
}
}
Main
public class Main {
public static void main(String[] args) {
String basepath = Main.class.getResource("").getPath();
// 获取Main的包名
String basepackage = Main.class.getPackage().getName();
HydIOC hydIOC = new HydIOC(basepath,basepackage);
hydIOC.initBeans();
HydController hydController = (HydController) hydIOC.getInstance(HydController.class.getName());
hydController.hydtest();
}
}
整体与之前的仿写MVC的思路相差不大,不做过多描述
跳转仿写MVC