diff --git a/.gitee/ISSUE_TEMPLATE.zh-CN.md b/.gitee/ISSUE_TEMPLATE.zh-CN.md
deleted file mode 100644
index f09d98dde9597de75ffcdb237c2b580b8fffa3f9..0000000000000000000000000000000000000000
--- a/.gitee/ISSUE_TEMPLATE.zh-CN.md
+++ /dev/null
@@ -1,13 +0,0 @@
-### 该问题是怎么引起的?
-
-
-
-### 重现步骤
-
-
-
-### 报错信息
-
-
-
-
diff --git a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md b/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md
deleted file mode 100644
index 66d4332058d27e3c8ef94919138576d71b524467..0000000000000000000000000000000000000000
--- a/.gitee/PULL_REQUEST_TEMPLATE.zh-CN.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### 相关的Issue
-
-
-### 原因(目的、解决的问题等)
-
-
-### 描述(做了什么,变更了什么)
-
-
-### 测试用例(新增、改动、可能影响的功能)
-
-
-
-
diff --git a/.gitignore b/.gitignore
index 5d947ca8879f8a9072fe485c566204e3c2929e80..0107921ca5d8692597f061b1ca57e14a171717af 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,8 @@ bin-release/
*.air
*.ipa
*.apk
-
+.idea/*
+target/*
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
# should NOT be excluded as they contain compiler settings and other important
# information for Eclipse / Flash Builder.
diff --git a/README.md b/README.md
index af9809c147a94fd3fe85c66335fb1a6e4d7253c8..119fcc7d395d5ff74736f4dcaebf1956312a44f4 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,14 @@
实现类似于Spring的容器管理工具,因为项目中不需要使用很重的Spring,而右希望能够拥有它的IOC,DI
#### 软件架构
-软件架构说明
-
-
+@Autowired 注入默认按照类型注入,name属性赋值则严格按照名称注入,没有则不注入
+@bean 类似于Spring的@Bean
+@Component 配置类和需要被容器托管的类必须写
+@Note 目前仅用于注释
+@BeanScanner 包扫描注解
+ContextBean.java 容器对bean的封装
+ContextHolder.java 容器
+ContextRun.java 容器启动器,只有调用其中的run方法,容器才能够正常启动
#### 安装教程
1. xxxx
@@ -14,10 +19,18 @@
3. xxxx
#### 使用说明
-
-1. xxxx
-2. xxxx
-3. xxxx
+```java
+/* 扫描bean的必备注解 */
+@BeanScanner(path = "org.needcoke.ioc")
+public class Main {
+
+ public static void main(String[] args) {
+ /* 一行代码轻松获取上下文 */
+ ContextHolder context = ContextRun.run(Main.class, args);
+
+ }
+}
+```
#### 参与贡献
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fe4513d069554373ade10cf4cbc2470beb433978
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,23 @@
+
+
+ 4.0.0
+
+ groupId
+ needcoke-ioc
+ 1.0-SNAPSHOT
+
+
+ 8
+ 8
+
+
+
+
+ cn.hutool
+ hutool-all
+ 5.5.1
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/needcoke/ioc/ContextRun.java b/src/main/java/org/needcoke/ioc/ContextRun.java
new file mode 100644
index 0000000000000000000000000000000000000000..839fbee104de685fa14de787936e94cda1480654
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/ContextRun.java
@@ -0,0 +1,114 @@
+package org.needcoke.ioc;
+
+import cn.hutool.core.util.StrUtil;
+import org.needcoke.ioc.annotation.Autowired;
+import org.needcoke.ioc.annotation.Bean;
+import org.needcoke.ioc.annotation.BeanScanner;
+import org.needcoke.ioc.annotation.Component;
+import org.needcoke.ioc.core.ContextBean;
+import org.needcoke.ioc.core.ContextHolder;
+import org.needcoke.ioc.util.MethodUtil;
+import org.needcoke.ioc.util.PackageUtil;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+public class ContextRun {
+
+ private static Object init(Class> clz) {
+ try {
+ return clz.newInstance();
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static ContextHolder run(Class> t, String[] args) {
+ ContextHolder holder = new ContextHolder();
+ BeanScanner annotation = t.getAnnotation(BeanScanner.class);
+ if (null != annotation) {
+ String[] paths = annotation.path();
+ boolean recursion = annotation.recursion();/* 是否递归加载类 */
+ for (String path : paths) {
+ /* 获取包路径下的所有类 */
+ Set> clzFromPkg = PackageUtil.getClzFromPkg(path);
+ for (Class> aClass : clzFromPkg) {
+ if (aClass.getAnnotation(Component.class) != null) {
+ Object component = init(aClass);
+ Method[] methods = aClass.getDeclaredMethods();
+ for (Method method : methods) {
+ Bean methodBean = method.getAnnotation(Bean.class);
+ if (null != methodBean) {
+
+ if (holder.nameBeanContext.containsKey(methodBean.name())) {
+ throw new RuntimeException("already has a bean name #" + methodBean.name() + "#");
+ } else {
+ /* 通过反射执行方法,并获取反射值,注解有声明名称则用注解,注解无则使用方法名,存入context */
+ ContextBean beanFromMethod = MethodUtil.runMethod(method, component, holder);
+ if (StrUtil.isBlank(methodBean.name())) {
+ beanFromMethod.name = method.getName();
+ }
+ holder.putBean(beanFromMethod);
+ }
+
+ }
+ }
+ ContextBean componentBean = new ContextBean();
+ String componentName = aClass.getAnnotation(Component.class).name();
+ if(StrUtil.isBlank(componentName)){
+ componentName = aClass.getSimpleName();
+ }
+ componentBean.name = componentName;
+ componentBean.clz = aClass;
+ componentBean.value = component;
+ holder.putComponent(componentBean);
+ }
+ }
+
+
+ }
+
+ Set> componentClasses = holder.componentMap.keySet();
+ for (Class> componentClass : componentClasses) {
+ Object component = holder.componentMap.get(componentClass);
+ Field[] fields = componentClass.getDeclaredFields();
+ for (Field field : fields) {
+ Autowired autowiredAnnotation = field.getAnnotation(Autowired.class);
+ if(null != autowiredAnnotation){
+ ContextBean beanAutowired = null;
+ /* Autowired的name属性不为空的话,就通过名称注入 */
+ if(StrUtil.isNotBlank(autowiredAnnotation.name())){
+ beanAutowired = holder.nameBeanContext.get(autowiredAnnotation.name());
+ if(null != beanAutowired && beanAutowired.clz.equals(field.getType())) {
+ try {
+ field.setAccessible(true);
+ field.set(component, beanAutowired.value);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ else{
+ /* 名称为空,则通过类型来匹配 */
+ if(holder.typeBeanContext.containsKey(field.getType())){
+ beanAutowired = holder.typeBeanContext.get(field.getType()).get(0);
+ try {
+ field.setAccessible(true);
+ field.set(component, beanAutowired.value);
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+ }
+ }
+ }
+ }
+ return holder;
+
+ }
+}
diff --git a/src/main/java/org/needcoke/ioc/annotation/Autowired.java b/src/main/java/org/needcoke/ioc/annotation/Autowired.java
new file mode 100644
index 0000000000000000000000000000000000000000..8780e4dfb59abd9781004fb197bf465898a83257
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/annotation/Autowired.java
@@ -0,0 +1,12 @@
+package org.needcoke.ioc.annotation;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Autowired {
+
+ @Note("bean的名称")
+ String name() default "";
+}
diff --git a/src/main/java/org/needcoke/ioc/annotation/Bean.java b/src/main/java/org/needcoke/ioc/annotation/Bean.java
new file mode 100644
index 0000000000000000000000000000000000000000..a57c2af6971dc5d569284e5dc11da13cd3bc0ccd
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/annotation/Bean.java
@@ -0,0 +1,11 @@
+package org.needcoke.ioc.annotation;
+
+import java.lang.annotation.*;
+
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Bean {
+ @Note("名称")
+ String name() default "";
+}
diff --git a/src/main/java/org/needcoke/ioc/annotation/BeanScanner.java b/src/main/java/org/needcoke/ioc/annotation/BeanScanner.java
new file mode 100644
index 0000000000000000000000000000000000000000..a627df367480678fcbd47e65f0409672ddc62555
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/annotation/BeanScanner.java
@@ -0,0 +1,17 @@
+package org.needcoke.ioc.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 项目启动时bean的扫描器
+ **/
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface BeanScanner {
+
+ @Note("扫描的包路径")
+ String[] path() default {};
+
+ boolean recursion() default false;
+}
diff --git a/src/main/java/org/needcoke/ioc/annotation/Component.java b/src/main/java/org/needcoke/ioc/annotation/Component.java
new file mode 100644
index 0000000000000000000000000000000000000000..a6e815ff4b494b58baf8fa1bd1e123f61395d179
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/annotation/Component.java
@@ -0,0 +1,11 @@
+package org.needcoke.ioc.annotation;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.TYPE_USE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Component {
+ @Note("名称")
+ String name() default "";
+}
diff --git a/src/main/java/org/needcoke/ioc/annotation/Note.java b/src/main/java/org/needcoke/ioc/annotation/Note.java
new file mode 100644
index 0000000000000000000000000000000000000000..3821018923f99ff83a02665773e3e908e857b8e3
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/annotation/Note.java
@@ -0,0 +1,17 @@
+package org.needcoke.ioc.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 用于做注释
+ *
+ * @author Gilgamesh
+ * @since 0.0.1start
+ **/
+@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Note {
+
+ String value() default "";
+}
diff --git a/src/main/java/org/needcoke/ioc/app/MainApp/Main.java b/src/main/java/org/needcoke/ioc/app/MainApp/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..25c100840395cbe835604c107340602e0379646b
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/app/MainApp/Main.java
@@ -0,0 +1,20 @@
+package org.needcoke.ioc.app.MainApp;
+
+import org.needcoke.ioc.ContextRun;
+import org.needcoke.ioc.annotation.BeanScanner;
+import org.needcoke.ioc.core.ContextHolder;
+import org.needcoke.ioc.test.A002;
+import java.util.List;
+
+@BeanScanner(path = "org.needcoke.ioc")
+public class Main {
+
+ public static void main(String[] args) {
+ ContextHolder run = ContextRun.run(Main.class, args);
+ List list = run.getBean(A002.class);
+
+ for (A002 a002 : list) {
+ a002.print();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/needcoke/ioc/core/ContextBean.java b/src/main/java/org/needcoke/ioc/core/ContextBean.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a2e7058e445a51adaeb46c8617fe861a31d6665
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/core/ContextBean.java
@@ -0,0 +1,27 @@
+package org.needcoke.ioc.core;
+
+
+public class ContextBean {
+
+ public Class> clz;
+
+ public Object value;
+
+ public String name;
+
+ public String id;
+
+ public E getValue(){
+ return (E) value;
+ }
+
+ @Override
+ public String toString() {
+ return "ContextBean{" +
+ "clz=" + clz +
+ ", value=" + value +
+ ", name='" + name + '\'' +
+ ", id='" + id + '\'' +
+ '}';
+ }
+}
diff --git a/src/main/java/org/needcoke/ioc/core/ContextHolder.java b/src/main/java/org/needcoke/ioc/core/ContextHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..189d1e640bd4b27e24442b500aa8f071313dc047
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/core/ContextHolder.java
@@ -0,0 +1,90 @@
+package org.needcoke.ioc.core;
+
+import cn.hutool.core.util.StrUtil;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class ContextHolder {
+
+ /**
+ * id计数器
+ **/
+ private AtomicLong idCounter = new AtomicLong(0);
+
+ /**
+ * 所有的component组件
+ **/
+ public Map, Object> componentMap = new ConcurrentHashMap<>();
+
+ /**
+ * ioc容器的id索引
+ **/
+ public Map idBeanMap = new ConcurrentHashMap<>();
+ /**
+ * ioc容器的名称索引
+ **/
+ public Map nameBeanContext = new ConcurrentHashMap<>();
+
+ /**
+ * ioc容器的类型索引
+ **/
+ public Map, List> typeBeanContext = new ConcurrentHashMap<>();
+
+ public List getBean(Class type) {
+ List ts = new ArrayList<>();
+ List contextBeans = typeBeanContext.get(type);
+ for (ContextBean contextBean : contextBeans) {
+ ts.add((T) contextBean.value);
+ }
+ return ts;
+ }
+
+ public T getBean(String name) {
+ return (T) nameBeanContext.get(name).value;
+ }
+
+ public T getBeanById(String id) {
+ return (T) idBeanMap.get(id).value;
+ }
+
+ public void putBean(ContextBean bean) {
+ if (StrUtil.isNotBlank(bean.name)) {
+ String name = bean.name;
+ int i = 1;
+ String suffix = "";
+ while (nameBeanContext.containsKey(name)) {
+ StrUtil.removeSuffix(name, suffix);
+ name += i++;
+ }
+ bean.name = name;
+ nameBeanContext.put(name, bean);
+ if (typeBeanContext.containsKey(bean.clz)) {
+ typeBeanContext.get(bean.clz).add(bean);
+ } else {
+ List beans = new ArrayList<>();
+ beans.add(bean);
+ typeBeanContext.put(bean.clz, beans);
+ }
+ if (StrUtil.isBlank(bean.id) || idBeanMap.containsKey(bean.id)) {
+ bean.id = applyForId().toString();
+ }
+ idBeanMap.put(bean.id, bean);
+ }
+ }
+
+ /**
+ * 向id计数器申请一个id
+ **/
+ private Long applyForId() {
+ return idCounter.addAndGet(1);
+ }
+
+ public void putComponent(ContextBean bean) {
+ componentMap.put(bean.clz, bean.value);
+ putBean(bean);
+ }
+
+}
diff --git a/src/main/java/org/needcoke/ioc/test/A002.java b/src/main/java/org/needcoke/ioc/test/A002.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d14ad176bce30563532e392df0e2edfd3bf6444
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/test/A002.java
@@ -0,0 +1,19 @@
+package org.needcoke.ioc.test;
+
+import org.needcoke.ioc.annotation.Autowired;
+import org.needcoke.ioc.annotation.Component;
+
+import java.util.Map;
+
+@Component
+public class A002 {
+
+ @Autowired(name = "vvsf")
+ private Map map;
+
+ public void print(){
+ for (String s : map.keySet()) {
+ System.out.println("s:"+s+"->"+map.get(s));
+ }
+ }
+}
diff --git a/src/main/java/org/needcoke/ioc/test/A01.java b/src/main/java/org/needcoke/ioc/test/A01.java
new file mode 100644
index 0000000000000000000000000000000000000000..28beb8551a4b890fe1e9d1d0c354f5272a4fd2a7
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/test/A01.java
@@ -0,0 +1,24 @@
+package org.needcoke.ioc.test;
+
+import org.needcoke.ioc.annotation.Bean;
+import org.needcoke.ioc.annotation.Component;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component(name = "DDS01")
+public class A01 {
+
+ @Bean
+ public Map map233() {
+ Map map = new ConcurrentHashMap<>();
+ map.put("abc","222");
+ return map;
+ }
+
+ @Bean
+ public Map vvsf(){
+ Map map = new ConcurrentHashMap<>();
+ map.put("awerwrqwrbc","wefrgerghtrgh");
+ return map;
+ }
+}
diff --git a/src/main/java/org/needcoke/ioc/util/MethodUtil.java b/src/main/java/org/needcoke/ioc/util/MethodUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc51c755660f5a345fac0c0b98ec63564130f50d
--- /dev/null
+++ b/src/main/java/org/needcoke/ioc/util/MethodUtil.java
@@ -0,0 +1,42 @@
+package org.needcoke.ioc.util;
+
+import org.needcoke.ioc.core.ContextBean;
+import org.needcoke.ioc.core.ContextHolder;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+public class MethodUtil {
+
+ /**
+ * 在反射中,未知参数列表调用函数获取返回值
+ *
+ * @param method 方法
+ * @param obj 调用方法的对象
+ * @param holder ioc上下文
+ * @author Gilgamesh
+ * @since 0.0.1start
+ **/
+ public static ContextBean runMethod(Method method, Object obj, ContextHolder holder) {
+ ContextBean bean = new ContextBean();
+ bean.name = method.getName();
+ bean.clz = method.getReturnType();
+ Class>[] parameterTypes = method.getParameterTypes();
+ List