问题描述:
- 初学者新接触到
Spring
容器的时候,总是各种懵。
- 不知道对象为什么可以在想要的地方,直接
@Autowired
一下,就可以用。
- 这篇文章就是通俗的讲讲,如何做到用
@Autowired
就可以获得想要的对象。
先想一想为什么要引入Spring
容器?
- 在实际的开发工作中,开发人员需要编写很多
Class
去完成一个功能的编写,完成一个事务的处理。
- 要使用一个
Class
去干活,我们先得new
一个这个Class
的实例对象对吧,会向JVM
(Java Virtual Machine)申请空间,然后才可以执行Class
中编写的非静态代码段。
- 如果没有
Spring
容器,那么每次new
出来的对象干完活,是不是得释放掉呀,避免占用空间对吧。
那么问题就来了,这样重复的对常用的Class去new对象,去释放对象,反而不如就让这些常用的Class保留一个对象对系统的资源开销小。于是Spring
容器,应运而生。就是为了解决此处的开发痛点而出现的。
Spring
容器的通俗理解:
Spring
容器的实际作用,老师们都应该讲过,就是一个承装对象的东西。
- 具体点,比如:可以将
Spring
容器理解为一个工具箱,工具箱里面可以有锤子、钳子、扳手、卷尺等等。
其实Spring
容器,也就主要干了三事情。
- 创建并保留对象实例。
- 给对象实例打上标记管理起来。
- 提供给外部通过实例对象的标记获取对象的接口。
实践,干!不怂:
下面来用简单的代码实现一个非常粗犷的Spring容器吧,跟着看一遍,就能懂了。
编码准备:
java JDK1.8
版本
IDE
工具,首选IntelliJ IDEA
(这个要收费,有点小贵,当然破解的方法我是不会告诉你们的,我公开是支持正版的),或者Eclipse
,不建议用MyEclipse
准备几个Class:
自定义注册注解:
1 2 3 4 5 6 7 8 9 10 11 12
| package com.example.demo.annotation;
import java.lang.annotation.*;
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyComponent { }
|
自定义绑定注解:
1 2 3 4 5 6 7 8 9 10 11 12
| package com.example.demo.annotation;
import java.lang.annotation.*;
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyAutowired { }
|
注册和数据绑定器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
public class Register {
private static Container container = new Container();
private static Container getContainer() { return container; }
private static boolean regist(Class<?> clzz){ Container container = Register.getContainer(); Map<String, Object> tools = container.getTools(); Object o = null; try { o = clzz.newInstance(); tools.put(clzz.getName(),o); return true; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return false; }
private static boolean myAutowired(){ Map<String, Object> tools = Register.getContainer().getTools();
tools.forEach((key,value)->{ Class<?> clzz = value.getClass(); Field[] fs = clzz.getDeclaredFields(); try { bindFields(value, fs, tools); } catch (IllegalAccessException e) { e.printStackTrace(); } });
return true; }
public static <T> T getBean(Class<T> clzz){ Map<String, Object> tools = Register.getContainer().getTools(); T t = (T) tools.get(Test.class.getName()); return t; }
private static boolean bindFields(Object obj,Field[] fields,Map<String, Object> tools) throws IllegalAccessException { for (Field field : fields) { if(field.isAnnotationPresent(MyAutowired.class)) { Class<?> type = field.getType(); Object tool = tools.get(type.getName()); if(tool!=null){ field.setAccessible(true); field.set(obj,tool); }else{ return false; } } } return true; }
public static boolean registAndAutoBind(ScanFileTool t) { t.findClassLocal(ScanFileTool.STARATEGY_PATH); List<Class<? extends String>> eleStrategyList = t.getEleStrategyList();
if(eleStrategyList!=null && eleStrategyList.size()>0){ eleStrategyList.forEach((clzz)->{ if(clzz.isAnnotationPresent(MyComponent.class)){ Register.regist(clzz); } }); }
Register.myAutowired();
return true; } }
|
使用@MyComponent注解:
1 2 3 4 5 6 7 8 9 10 11 12
| package com.example.demo.tools;
import com.example.demo.annotation.MyComponent;
@MyComponent public class Hamer extends Tool {
}
|
准备抽象类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.example.demo.tools;
import com.alibaba.fastjson.JSON;
public abstract class Tool {
public String getToolName() { return getClass().getName(); }
@Override public String toString() { return JSON.toJSONString(this); } }
|
使用自定义注解@MyComponent注册,使用@MyAutowired绑定注入数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.example.demo.tools.test;
import com.example.demo.annotation.MyAutowired; import com.example.demo.annotation.MyComponent; import com.example.demo.tools.Hamer;
@MyComponent public class Test {
@MyAutowired private Hamer hamer;
public void printHamerName(){ System.out.println("Test : "+hamer.getToolName()); }
}
|
以上方法和类的放心食用方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.example.demo;
import com.example.demo.register.Register; import com.example.demo.tools.test.Test; import com.example.demo.utils.ScanFileTool;
import java.net.URISyntaxException;
public class DemoApplication {
public static void main(String[] args) throws URISyntaxException {
ScanFileTool t = new ScanFileTool();
boolean b = Register.registAndAutoBind(t);
Test test = Register.getBean(Test.class);
test.printHamerName();
}
}
|
流程如下:
1 2 3
| graph TD A[扫描包ScanFileTool] -- 注册 --> B[容器Map] -- 绑定 --> C[绑定对象] --> D[容器准备完毕] -- 根据类名 --> E[获取/使用对象]
|
相关代码下载链接:点此下载
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !