├── .classpath ├── .gitignore ├── .idea ├── checkstyle-idea.xml ├── compiler.xml ├── encodings.xml ├── inspectionProfiles │ └── Project_Default.xml ├── libraries │ └── Maven__junit_junit_4_7.xml ├── misc.xml ├── modules.xml ├── vcs.xml └── workspace.xml ├── .project ├── .settings ├── org.eclipse.jdt.core.prefs └── org.eclipse.m2e.core.prefs ├── myspring.iml ├── pom.xml ├── readme.md └── src ├── main ├── java │ └── cn │ │ └── thinkinjava │ │ └── myspring │ │ ├── AbstractBeanDefinitionReader.java │ │ ├── BeanDefinition.java │ │ ├── BeanDefinitionReader.java │ │ ├── BeanReference.java │ │ ├── PropertyValue.java │ │ ├── PropertyValues.java │ │ ├── factory │ │ ├── AbstractBeanFactory.java │ │ ├── AutowireBeanFactory.java │ │ └── BeanFactory.java │ │ ├── io │ │ ├── Resource.java │ │ ├── ResourceLoader.java │ │ └── ResourceUrl.java │ │ └── xml │ │ └── XmlBeanDefinitionReader.java └── resources │ └── myspring.xml └── test ├── java ├── cn │ └── thinkinjava │ │ └── myspring │ │ └── test │ │ ├── BeanFactoryTest.java │ │ ├── HelloWorld.java │ │ ├── ReferenceBean.java │ │ └── XmlBeanDefinitionReaderTest.java └── intecode │ └── Test.java └── resources └── myspring.xml /.classpath: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .idea 3 | .project 4 | .classpath 5 | myspring.iml 6 | .settings 7 | 8 | -------------------------------------------------------------------------------- /.idea/checkstyle-idea.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 36 | -------------------------------------------------------------------------------- /.idea/libraries/Maven__junit_junit_4_7.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 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 | 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 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 173 | 174 | 177 | 178 | 179 | 230 | 231 | 232 | 233 | 234 | true 235 | DEFINITION_ORDER 236 | 237 | 238 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 415 | 416 | 417 | 418 | 419 | 420 | 423 | 424 | 425 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 448 | 449 | 450 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 473 | 474 | 486 | 487 | 488 | 489 | 492 | 493 | 494 | 508 | 509 | 510 | 511 | 512 | 517 | 518 | 519 | 531 | 532 | 533 | 534 | 548 | 549 | 550 | 551 | 552 | 553 | 557 | 558 | 564 | 565 | 566 | 567 | 585 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 609 | 610 | 611 | 612 | 1511966464152 613 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 691 | 692 | 694 | 695 | 696 | 697 | 698 | file://$PROJECT_DIR$/src/test/java/cn/thinkinjava/myspring/test/BeanFactoryTest.java 699 | 29 700 | 701 | 703 | 704 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | JAVA 967 | cn.thinkinjava.myspring.factory.AbstractBeanFactory 968 | 969 | cn.thinkinjava.myspring.factory.BeanFactory 970 | cn.thinkinjava.myspring.PropertyValues 971 | cn.thinkinjava.myspring.factory.AbstractBeanFactory 972 | cn.thinkinjava.myspring.BeanReference 973 | cn.thinkinjava.myspring.io.ResourceUrl 974 | cn.thinkinjava.myspring.io.Resource 975 | cn.thinkinjava.myspring.io.ResourceLoader 976 | cn.thinkinjava.myspring.AbstractBeanDefinitionReader 977 | cn.thinkinjava.myspring.factory.AutowireBeanFactory 978 | cn.thinkinjava.myspring.BeanDefinition 979 | cn.thinkinjava.myspring.PropertyValue 980 | cn.thinkinjava.myspring.xml.XmlBeanDefinitionReader 981 | cn.thinkinjava.myspring.BeanDefinitionReader 982 | 983 | 984 | 985 | 986 | 987 | 988 | Constructors 989 | 990 | All 991 | private 992 | 993 | 994 | 995 | 996 | 997 | 998 | JAVA 999 | cn.thinkinjava.myspring 1000 | 1001 | cn.thinkinjava.myspring.AbstractBeanDefinitionReader 1002 | cn.thinkinjava.myspring.BeanDefinition 1003 | cn.thinkinjava.myspring.PropertyValue 1004 | cn.thinkinjava.myspring.PropertyValues 1005 | cn.thinkinjava.myspring.io 1006 | cn.thinkinjava.myspring.BeanReference 1007 | cn.thinkinjava.myspring.BeanDefinitionReader 1008 | cn.thinkinjava.myspring.factory 1009 | cn.thinkinjava.myspring.test 1010 | cn.thinkinjava.myspring.xml 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | All 1018 | private 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | 1164 | 1165 | 1166 | 1167 | 1168 | 1169 | 1170 | 1171 | 1172 | 1173 | 1174 | 1175 | 1176 | 1177 | 1178 | 1179 | 1180 | 1181 | 1182 | 1183 | 1184 | 1185 | 1190 | 1191 | 1192 | 1193 | 1194 | 1195 | Spring 1196 | 1197 | 1202 | 1203 | 1204 | 1205 | 1206 | 1207 | commons-beanutils 1208 | 1209 | 1214 | 1215 | 1216 | 1217 | 1218 | 1219 | 1.8 1220 | 1221 | 1226 | 1227 | 1228 | 1229 | 1230 | 1231 | Spring|myspring 1232 | 1233 | 1238 | 1239 | 1240 | 1241 | 1242 | 1243 | 1.8 1244 | 1245 | 1250 | 1251 | 1252 | 1253 | 1254 | 1255 | Maven: junit:junit:4.7 1256 | 1257 | 1262 | 1263 | 1264 | 1265 | 1266 | 1267 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | myspring 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.m2e.core.maven2Builder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.m2e.core.maven2Nature 22 | 23 | 24 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 3 | org.eclipse.jdt.core.compiler.compliance=1.5 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.5 6 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /myspring.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.yuannauy 7 | myspring 8 | 0.0.1-SNAPSHOT 9 | 10 | 11 | 12 | org.apache.maven.plugins 13 | maven-compiler-plugin 14 | 15 | 1.7 16 | 1.7 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | junit 25 | junit 26 | 4.7 27 | test 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 自己实现一个简单的IOC 2 | 3 | 本人微信,欢迎一起探讨: 4 | 5 | ![image](https://user-images.githubusercontent.com/24973360/50372024-5f975d00-0601-11e9-8247-139e145b1123.png) 6 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/AbstractBeanDefinitionReader.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring; 2 | 3 | import cn.thinkinjava.myspring.io.ResourceLoader; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | /** 8 | * 抽象的bean定义读取类 9 | * 10 | * @author stateis0 11 | */ 12 | public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader { 13 | 14 | /** 15 | * 注册bean容器 16 | */ 17 | private Map registry; 18 | 19 | /** 20 | * 资源加载器 21 | */ 22 | private ResourceLoader resourceLoader; 23 | 24 | /** 25 | * 构造器器必须有一个资源加载器, 默认插件创建一个map容器 26 | * 27 | * @param resourceLoader 资源加载器 28 | */ 29 | protected AbstractBeanDefinitionReader(ResourceLoader resourceLoader) { 30 | this.registry = new HashMap<>(); 31 | this.resourceLoader = resourceLoader; 32 | } 33 | 34 | /** 35 | * 获取容器 36 | */ 37 | public Map getRegistry() { 38 | return registry; 39 | } 40 | 41 | /** 42 | * 获取资源加载器 43 | */ 44 | public ResourceLoader getResourceLoader() { 45 | return resourceLoader; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/BeanDefinition.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring; 2 | 3 | /** 4 | * bean 的定义 5 | * 6 | * @author stateis0 7 | */ 8 | public class BeanDefinition { 9 | 10 | /** 11 | * bean 12 | */ 13 | private Object bean; 14 | 15 | /** 16 | * bean 的 CLass 对象 17 | */ 18 | private Class beanClass; 19 | 20 | /** 21 | * bean 的类全限定名称 22 | */ 23 | private String ClassName; 24 | 25 | /** 26 | * 类的属性集合 27 | */ 28 | private PropertyValues propertyValues = new PropertyValues(); 29 | 30 | /** 31 | * 获取bean对象 32 | */ 33 | public Object getBean() { 34 | return this.bean; 35 | } 36 | 37 | /** 38 | * 设置bean的对象 39 | */ 40 | public void setBean(Object bean) { 41 | this.bean = bean; 42 | } 43 | 44 | /** 45 | * 获取bean的Class对象 46 | */ 47 | public Class getBeanclass() { 48 | return this.beanClass; 49 | } 50 | 51 | /** 52 | * 通过设置类名称反射生成Class对象 53 | */ 54 | public void setClassname(String name) { 55 | this.ClassName = name; 56 | try { 57 | this.beanClass = Class.forName(name); 58 | } catch (ClassNotFoundException e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | 63 | /** 64 | * 获取bean的属性集合 65 | */ 66 | public PropertyValues getPropertyValues() { 67 | return this.propertyValues; 68 | } 69 | 70 | /** 71 | * 设置bean的属性 72 | */ 73 | public void setPropertyValues(PropertyValues pv) { 74 | this.propertyValues = pv; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/BeanDefinitionReader.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring; 2 | 3 | /** 4 | * 读取bean定义的接口 5 | */ 6 | public interface BeanDefinitionReader { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/BeanReference.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring; 2 | 3 | /** 4 | * bean的引用 5 | * 6 | * @author stateis0 7 | */ 8 | public class BeanReference { 9 | 10 | /** 11 | * bean名称 12 | */ 13 | private String name; 14 | /** 15 | * bean 对象 16 | */ 17 | private Object bean; 18 | 19 | /** 20 | * 构造器, 必须包含一个bean名称 21 | */ 22 | public BeanReference(String name) { 23 | this.name = name; 24 | } 25 | 26 | /** 27 | * 设置bean名称 28 | */ 29 | public void setName(String name) { 30 | this.name = name; 31 | } 32 | 33 | /** 34 | * 获取bean名称 35 | */ 36 | public String getName() { 37 | return this.name; 38 | } 39 | 40 | /** 41 | * 设置bean 对象 42 | */ 43 | public void setBean(Object bean) { 44 | this.bean = bean; 45 | } 46 | 47 | /** 48 | * 获取bean对象 49 | */ 50 | public Object getBean() { 51 | return this.bean; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/PropertyValue.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring; 2 | 3 | /** 4 | * 属性定义 5 | * 6 | * @author stateis0 7 | */ 8 | public class PropertyValue { 9 | 10 | /** 11 | * 属性名称 12 | */ 13 | private final String name; 14 | 15 | /** 16 | * 属性对象 17 | */ 18 | private final Object value; 19 | 20 | /** 21 | * 构造器: 需要一个属性名称,一个属性对象 22 | */ 23 | public PropertyValue(String name, Object value) { 24 | this.name = name; 25 | this.value = value; 26 | } 27 | 28 | /** 29 | * 获取属性名称 30 | */ 31 | public String getname() { 32 | return this.name; 33 | } 34 | 35 | /** 36 | * 获取属性对象 37 | */ 38 | public Object getvalue() { 39 | return this.value; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/PropertyValues.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * 属性集合 8 | * 9 | * @author stateis0 10 | */ 11 | public class PropertyValues { 12 | 13 | /** 14 | * 属性list 15 | */ 16 | private final List propertyValueList = new ArrayList<>(); 17 | 18 | /** 19 | * 默认构造器 20 | */ 21 | public PropertyValues() { 22 | } 23 | 24 | /** 25 | * 添加进属性集合 26 | */ 27 | public void addPropertyValue(PropertyValue pv) { 28 | propertyValueList.add(pv); 29 | } 30 | 31 | /** 32 | * 获取属性集合 33 | */ 34 | public List getPropertyValues() { 35 | return propertyValueList; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/factory/AbstractBeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.factory; 2 | 3 | import cn.thinkinjava.myspring.BeanDefinition; 4 | import java.util.HashMap; 5 | 6 | /** 7 | * 一个抽象类, 实现了 bean 的方法,包含一个map,用于存储bean 的名字和bean的定义 8 | * 9 | * @author stateis0 10 | */ 11 | public abstract class AbstractBeanFactory implements BeanFactory { 12 | 13 | /** 14 | * 容器 15 | */ 16 | private HashMap map = new HashMap<>(); 17 | 18 | /** 19 | * 根据bean的名称获取bean, 如果没有,则抛出异常 如果有, 则从bean定义对象获取bean实例 20 | */ 21 | @Override 22 | public Object getBean(String name) throws Exception { 23 | BeanDefinition beandefinition = map.get(name); 24 | if (beandefinition == null) { 25 | throw new IllegalArgumentException("No bean named " + name + " is defined"); 26 | } 27 | Object bean = beandefinition.getBean(); 28 | if (bean == null) { 29 | bean = doCreate(beandefinition); 30 | } 31 | return bean; 32 | } 33 | 34 | /** 35 | * 注册 bean定义 的抽象方法实现,这是一个模板方法, 调用子类方法doCreate, 36 | */ 37 | @Override 38 | public void registerBeanDefinition(String name, BeanDefinition beandefinition) throws Exception { 39 | Object bean = doCreate(beandefinition); 40 | beandefinition.setBean(bean); 41 | map.put(name, beandefinition); 42 | } 43 | 44 | /** 45 | * 减少一个bean 46 | */ 47 | abstract Object doCreate(BeanDefinition beandefinition) throws Exception; 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/factory/AutowireBeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.factory; 2 | 3 | import cn.thinkinjava.myspring.BeanDefinition; 4 | import cn.thinkinjava.myspring.PropertyValue; 5 | import cn.thinkinjava.myspring.BeanReference; 6 | import java.lang.reflect.Field; 7 | 8 | 9 | /** 10 | * 实现自动注入和递归注入(spring 的标准实现类 DefaultListableBeanFactory 有 1810 行) 11 | * 12 | * @author stateis0 13 | */ 14 | public class AutowireBeanFactory extends AbstractBeanFactory { 15 | 16 | 17 | /** 18 | * 根据bean 定义创建实例, 并将实例作为key, bean定义作为value存放,并调用 addPropertyValue 方法 为给定的bean的属性进行注入 19 | */ 20 | @Override 21 | protected Object doCreate(BeanDefinition beandefinition) throws Exception { 22 | Object bean = beandefinition.getBeanclass().newInstance(); 23 | addPropertyValue(bean, beandefinition); 24 | return bean; 25 | } 26 | 27 | /** 28 | * 给定一个bean定义和一个bean实例,为给定的bean中的属性注入实例。 29 | */ 30 | protected void addPropertyValue(Object bean, BeanDefinition beandefinition) throws Exception { 31 | // 循环给定 bean 的属性集合 32 | for (PropertyValue pv : beandefinition.getPropertyValues().getPropertyValues()) { 33 | // 根据给定属性名称获取 给定的bean中的属性对象 34 | Field declaredField = bean.getClass().getDeclaredField(pv.getname()); 35 | // 设置属性的访问权限 36 | declaredField.setAccessible(true); 37 | // 获取定义的属性中的对象 38 | Object value = pv.getvalue(); 39 | // 判断这个对象是否是 BeanReference 对象 40 | if (value instanceof BeanReference) { 41 | // 将属性对象转为 BeanReference 对象 42 | BeanReference beanReference = (BeanReference) value; 43 | // 调用父类的 AbstractBeanFactory 的 getBean 方法,根据bean引用的名称获取实例,此处即是递归 44 | value = getBean(beanReference.getName()); 45 | } 46 | // 反射注入bean的属性 47 | declaredField.set(bean, value); 48 | } 49 | 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/factory/BeanFactory.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.factory; 2 | 3 | import cn.thinkinjava.myspring.BeanDefinition; 4 | 5 | /** 6 | * 需要一个beanFactory 定义ioc 容器的一些行为 比如根据名称获取bean, 比如注册bean,参数为bean的名称,bean的定义 7 | * 8 | * @author stateis0 9 | * @version 1.0.0 10 | * @Date 2017/11/30 11 | */ 12 | public interface BeanFactory { 13 | 14 | /** 15 | * 根据bean的名称从容器中获取bean对象 16 | * 17 | * @param name bean 名称 18 | * @return bean实例 19 | * @throws Exception 异常 20 | */ 21 | Object getBean(String name) throws Exception; 22 | 23 | /** 24 | * 将bean注册到容器中 25 | * 26 | * @param name bean 名称 27 | * @param bean bean实例 28 | * @throws Exception 异常 29 | */ 30 | void registerBeanDefinition(String name, BeanDefinition bean) throws Exception; 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/io/Resource.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.io; 2 | 3 | import java.io.InputStream; 4 | 5 | /** 6 | * 资源定义 7 | * 8 | * @author stateis0 9 | */ 10 | public interface Resource { 11 | 12 | /** 13 | * 获取输入流 14 | */ 15 | InputStream getInputstream() throws Exception; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/io/ResourceLoader.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.io; 2 | 3 | import java.net.URL; 4 | 5 | /** 6 | * 资源加载器 7 | * 8 | * @author stateis0 9 | */ 10 | public class ResourceLoader { 11 | 12 | /** 13 | * 给定一个位置, 使用累加器的资源加载URL,并创建一个“资源URL”对象,便于获取输入流 14 | */ 15 | public ResourceUrl getResource(String location) { 16 | URL url = this.getClass().getClassLoader().getResource(location); 17 | return new ResourceUrl(url); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/io/ResourceUrl.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.io; 2 | 3 | import java.io.InputStream; 4 | import java.net.URL; 5 | import java.net.URLConnection; 6 | 7 | /** 8 | * 资源URL 9 | */ 10 | public class ResourceUrl implements Resource { 11 | 12 | /** 13 | * 类库URL 14 | */ 15 | private final URL url; 16 | 17 | /** 18 | * 需要一个类库URL 19 | */ 20 | public ResourceUrl(URL url) { 21 | this.url = url; 22 | } 23 | 24 | /** 25 | * 从URL中获取输入流 26 | */ 27 | @Override 28 | public InputStream getInputstream() throws Exception { 29 | URLConnection urlConnection = url.openConnection(); 30 | urlConnection.connect(); 31 | return urlConnection.getInputStream(); 32 | 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/cn/thinkinjava/myspring/xml/XmlBeanDefinitionReader.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stateIs0/simpleIoc/a1c0ef6133256c72ca81e5dc12b2f031009ecc35/src/main/java/cn/thinkinjava/myspring/xml/XmlBeanDefinitionReader.java -------------------------------------------------------------------------------- /src/main/resources/myspring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/test/java/cn/thinkinjava/myspring/test/BeanFactoryTest.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stateIs0/simpleIoc/a1c0ef6133256c72ca81e5dc12b2f031009ecc35/src/test/java/cn/thinkinjava/myspring/test/BeanFactoryTest.java -------------------------------------------------------------------------------- /src/test/java/cn/thinkinjava/myspring/test/HelloWorld.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.test; 2 | 3 | public class HelloWorld { 4 | 5 | private String text; 6 | 7 | void say() { 8 | System.out.println(text); 9 | } 10 | 11 | public String getText() { 12 | return text; 13 | } 14 | 15 | public void setText(String text) { 16 | this.text = text; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/cn/thinkinjava/myspring/test/ReferenceBean.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.test; 2 | 3 | public class ReferenceBean { 4 | 5 | private HelloWorld hello; 6 | 7 | public void say() { 8 | hello.say(); 9 | } 10 | 11 | public void setHello(HelloWorld hello) { 12 | this.hello = hello; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/cn/thinkinjava/myspring/test/XmlBeanDefinitionReaderTest.java: -------------------------------------------------------------------------------- 1 | package cn.thinkinjava.myspring.test; 2 | 3 | import cn.thinkinjava.myspring.BeanDefinition; 4 | import cn.thinkinjava.myspring.factory.AutowireBeanFactory; 5 | import cn.thinkinjava.myspring.factory.BeanFactory; 6 | import cn.thinkinjava.myspring.io.ResourceLoader; 7 | import cn.thinkinjava.myspring.xml.XmlBeanDefinitionReader; 8 | import java.util.Map; 9 | import org.junit.Test; 10 | 11 | public class XmlBeanDefinitionReaderTest { 12 | 13 | @Test 14 | public void test() throws Exception { 15 | // 创建一个XML解析器,携带一个资源加载器 16 | XmlBeanDefinitionReader xml = new XmlBeanDefinitionReader(new ResourceLoader()); 17 | // 解析该文件 18 | xml.readerXML("myspring.xml"); 19 | 20 | // 创建一个自动注入bean工厂 21 | BeanFactory beanfactory = new AutowireBeanFactory(); 22 | // 循环xml中的所有bean 23 | for (Map.Entry beanDefinitionEntry : xml.getRegistry().entrySet()) { 24 | // 将XML容器中的bean注册到bean工厂 25 | beanfactory 26 | .registerBeanDefinition(beanDefinitionEntry.getKey(), beanDefinitionEntry.getValue()); 27 | } 28 | // 获取持有另一个bean对象的bean(也是从容器中取得的) 29 | ReferenceBean hello = (ReferenceBean) beanfactory.getBean("referenceBean"); 30 | 31 | // 调用对象方法 32 | hello.say(); 33 | 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/intecode/Test.java: -------------------------------------------------------------------------------- 1 | package intecode; 2 | 3 | public class Test { 4 | 5 | public static void main(String[] args) { 6 | String n = "3.72"; 7 | int len = n.length(); 8 | String str = n.substring(n.indexOf("."), len); 9 | double right = Double.parseDouble(("0" + str)); 10 | System.out.println("" + right); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/test/resources/myspring.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | --------------------------------------------------------------------------------