├── .coveralls.yml ├── .gitignore ├── .travis.yml ├── CHANGE_LOG.md ├── LICENSE.txt ├── README.md ├── cgit.bat ├── cgit.sh ├── docs ├── README.md ├── issues │ ├── v0.0.1-beanFactory初始化.md │ ├── v0.0.2-beanFactory-listableFactory.md │ ├── v0.0.3-beanFactory-singleton-lazyInit.md │ ├── v0.0.4-beanFactory-init-destroy-对象的初始化销毁方法.md │ ├── v0.0.5-beanFactory-respcode-统一处理.md │ ├── v0.0.6-beanFactory-constructor-factoryMethod.md │ ├── v0.0.7-beanFactory-property-属性设置.md │ ├── v0.0.8-life-cycle-aware.md │ ├── v0.0.9-parent-依赖继承.md │ ├── v0.1.0-循环依赖问题.md │ ├── v0.1.1-annotation-@Configuration.md │ ├── v0.1.10-annotation-property-@Value.md │ ├── v0.1.11-annotation-@Component-classfiles.md │ ├── v0.1.19-annotation-@Component-jars.md │ ├── v0.1.2-annotation-@Bean.md │ ├── v0.1.3-annotation-@Lazy-@Scope.md │ ├── v0.1.4-annotation-@Role-@Import.md │ ├── v0.1.5-annotation-@Bean-constructor-@Description.md │ ├── v0.1.6-annotation-@Autowired.md │ ├── v0.1.7-annotation-@Primary.md │ ├── v0.1.8-annotation-@Condition.md │ ├── v0.1.9-annotation-Env-@Profile.md │ ├── v0.2.1-beanFactory-java源码配置支持.md │ ├── v0.2.1-beanFactory-resource-reader优化实现.md │ └── v0.3.2-beanFactory-xml配置支持.md └── user │ ├── 01-BeanFactory.md │ └── 02-ListableBeanFactory.md ├── pom.xml ├── release.bat ├── release.sh ├── release_rm.sh └── src ├── main └── java │ └── com │ └── github │ └── houbb │ └── ioc │ ├── annotation │ ├── Autowired.java │ ├── Bean.java │ ├── Component.java │ ├── ComponentScan.java │ ├── Conditional.java │ ├── Configuration.java │ ├── Description.java │ ├── FactoryMethod.java │ ├── Import.java │ ├── Lazy.java │ ├── Primary.java │ ├── Profile.java │ ├── PropertiesResource.java │ ├── Role.java │ ├── Scope.java │ ├── Service.java │ ├── Value.java │ └── package-info.java │ ├── constant │ ├── AnnotationConst.java │ ├── ProfileConst.java │ ├── ScopeConst.java │ ├── enums │ │ ├── BeanSourceTypeEnum.java │ │ ├── ScopeEnum.java │ │ └── package-info.java │ └── package-info.java │ ├── context │ ├── AbstractApplicationContext.java │ ├── AnnotationApplicationContext.java │ ├── ApplicationContext.java │ ├── JsonApplicationContext.java │ └── package-info.java │ ├── core │ ├── BeanFactory.java │ ├── ConfigableBeanFactory.java │ ├── ListableBeanFactory.java │ └── impl │ │ ├── DefaultBeanFactory.java │ │ └── DefaultListableBeanFactory.java │ ├── exception │ ├── IocAdviceRuntimeException.java │ ├── IocRuntimeException.java │ └── respcode │ │ └── IocRespCode.java │ ├── model │ ├── AnnotationBeanDefinition.java │ ├── BeanDefinition.java │ ├── ConstructorArgDefinition.java │ ├── PropertyArgDefinition.java │ ├── impl │ │ ├── DefaultAnnotationBeanDefinition.java │ │ ├── DefaultBeanDefinition.java │ │ ├── DefaultConstructorArgDefinition.java │ │ └── DefaultPropertyArgDefinition.java │ ├── meta │ │ ├── AnnotationMeta.java │ │ ├── BaseAnnotationMeta.java │ │ ├── BaseMeta.java │ │ ├── ClassMeta.java │ │ ├── FieldMeta.java │ │ ├── MethodMeta.java │ │ ├── ParamMeta.java │ │ └── package-info.java │ └── package-info.java │ ├── package-info.java │ └── support │ ├── annotation │ ├── Lazys.java │ ├── Scopes.java │ └── package-info.java │ ├── aware │ ├── ApplicationContextAware.java │ ├── Aware.java │ ├── BeanCreateAware.java │ ├── BeanFactoryAware.java │ ├── BeanNameAware.java │ └── service │ │ ├── AwareService.java │ │ └── impl │ │ └── DefaultAwareService.java │ ├── condition │ ├── Condition.java │ ├── ConditionContext.java │ ├── impl │ │ ├── DefaultConditionContext.java │ │ └── ProfileCondition.java │ └── package-info.java │ ├── converter │ ├── StringValueConverter.java │ └── StringValueConverterFactory.java │ ├── cycle │ ├── DependsCheckService.java │ └── impl │ │ └── DefaultDependsCheckService.java │ ├── definition │ └── package-info.java │ ├── envrionment │ ├── ConfigurableEnvironment.java │ ├── ConfigurablePropertyResolver.java │ ├── Environment.java │ ├── EnvironmentCapable.java │ ├── PropertyResolver.java │ ├── PropertySource.java │ └── impl │ │ ├── DefaultEnvironment.java │ │ ├── MapPropertySource.java │ │ ├── PropertiesPropertySource.java │ │ └── PropertySourcesPropertyResolver.java │ ├── lifecycle │ ├── DisposableBean.java │ ├── InitializingBean.java │ ├── NewInstanceBean.java │ ├── create │ │ ├── AbstractNewInstanceBean.java │ │ ├── ConfigurationMethodBean.java │ │ ├── ConstructorNewInstanceBean.java │ │ ├── DefaultNewInstanceBean.java │ │ └── FactoryMethodNewInstanceBean.java │ ├── destroy │ │ └── DefaultPreDestroyBean.java │ ├── init │ │ └── DefaultPostConstructBean.java │ ├── package-info.java │ ├── property │ │ ├── BeanPropertyProcessor.java │ │ ├── SingleBeanPropertyProcessor.java │ │ └── impl │ │ │ ├── DefaultBeanPropertyProcessor.java │ │ │ ├── RefBeanPropertyProcessor.java │ │ │ └── ValueBeanPropertyProcessor.java │ ├── registry │ │ ├── BeanDefinitionRegistry.java │ │ └── impl │ │ │ └── DefaultBeanDefinitionRegistry.java │ └── service │ │ ├── BeanLifecycleService.java │ │ └── impl │ │ └── DefaultBeanLifecycleService.java │ ├── name │ ├── BeanNameStrategy.java │ └── impl │ │ └── DefaultBeanNameStrategy.java │ ├── order │ └── Order.java │ ├── package-info.java │ ├── processor │ ├── ApplicationContextPostProcessor.java │ ├── BeanPostProcessor.java │ ├── PostProcessor.java │ └── impl │ │ ├── AutowiredAnnotationBeanPostProcessor.java │ │ └── BeanPostProcessorAdaptor.java │ └── scanner │ ├── AnnotationBeanDefinitionScanner.java │ ├── BeanDefinitionScannerContext.java │ ├── TypeFilter.java │ └── impl │ ├── AnnotatedTypeFilter.java │ ├── ClassPathAnnotationBeanDefinitionScanner.java │ └── DefaultBeanDefinitionScannerContext.java └── test ├── java └── com │ └── github │ └── houbb │ └── ioc │ └── test │ ├── config │ ├── AppAutowiredCollectionConfig.java │ ├── AppAutowiredConfig.java │ ├── AppAutowiredEnvConfig.java │ ├── AppAutowiredPrimaryConfig.java │ ├── AppBeanConditionConfig.java │ ├── AppBeanConfig.java │ ├── AppBeanLazyScopeConfig.java │ ├── AppBeanProfileConfig.java │ ├── AppBeanRefConfig.java │ ├── AppComponentScanConfig.java │ ├── AppComponentScanFilterConfig.java │ ├── AppConfig.java │ ├── AppImportConfig.java │ ├── AppMultiBeanConfig.java │ ├── AppPropertyResourceValueConfig.java │ ├── AppPropertyValueConfig.java │ └── package-info.java │ ├── context │ ├── AnnotationApplicationContextTest.java │ ├── ConfigBeanApplicationContextTest.java │ ├── ConfigBeanLazyScopeAppCtxTest.java │ ├── ConfigImportAppCtxTest.java │ └── JsonApplicationContextTest.java │ ├── core │ ├── BeanFactoryTest.java │ ├── BeanPropertyTest.java │ ├── CircleTest.java │ ├── GenJsonTest.java │ ├── InitTest.java │ ├── ListableBeanFactoryTest.java │ ├── NewInstanceTest.java │ └── ParentTest.java │ ├── model │ ├── Book.java │ └── User.java │ ├── package-info.java │ ├── service │ ├── Apple.java │ ├── ColorApple.java │ ├── ColorWeightApple.java │ ├── WeightApple.java │ └── inner │ │ ├── QueryService.java │ │ └── QueryServiceManager.java │ ├── support │ ├── condition │ │ ├── FalseCondition.java │ │ └── TrueCondition.java │ └── package-info.java │ └── util │ └── ClassUtilTest.java └── resources ├── apple.json ├── apples.json ├── circle ├── direct-circle.json └── in-direct-circle.json ├── create └── colorApple.json ├── name.properties ├── parent └── user-parent.json ├── property └── user-property.json └── singleton ├── apple-prototype.json └── apple-singleton.json /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # maven ignore 2 | target/ 3 | *.jar 4 | *.war 5 | *.zip 6 | *.tar 7 | *.tar.gz 8 | 9 | # eclipse ignore 10 | .settings/ 11 | .project 12 | .classpath 13 | 14 | # idea ignore 15 | .idea/ 16 | *.ipr 17 | *.iml 18 | *.iws 19 | 20 | # temp ignore 21 | *.log 22 | *.cache 23 | *.diff 24 | *.patch 25 | *.tmp 26 | *.java~ 27 | *.properties~ 28 | *.xml~ 29 | 30 | # system ignore 31 | .DS_Store 32 | Thumbs.db 33 | 34 | # logs 35 | logs 36 | 37 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk7 4 | install: mvn install -DskipTests=true -Dmaven.javadoc.skip=true 5 | script: mvn test 6 | after_success: 7 | - mvn clean cobertura:cobertura coveralls:report 8 | 9 | -------------------------------------------------------------------------------- /CHANGE_LOG.md: -------------------------------------------------------------------------------- 1 | # 变更日志 2 | 3 | | 类型 | 说明 | 4 | |:----|:----| 5 | | A | 新增 | 6 | | U | 更新 | 7 | | D | 删除 | 8 | | T | 测试 | 9 | | O | 优化 | 10 | | F | 修复BUG | 11 | 12 | # release_0.0.1 13 | 14 | | 序号 | 变化 | 时间 | 说明 | 15 | | 1 | A | 2019-11-6 22:56:55 | 添加最基本的 JSON 对象属性管理 | 16 | 17 | # release_0.0.2 18 | 19 | | 序号 | 变化 | 时间 | 说明 | 20 | | 1 | A | 2019-11-8 13:24:51 | 添加 BeanFactory 新特性 | 21 | | 2 | A | 2019-11-8 13:24:51 | 新增 ListableBeanFactory 接口及其默认实现类 | 22 | 23 | # release_0.0.3 24 | 25 | | 序号 | 变化 | 时间 | 说明 | 26 | | 1 | A | 2019-11-8 13:24:51 | 新增 lazy-init 处理 | 27 | | 2 | A | 2019-11-8 13:24:51 | 新增 scope 特性 | 28 | 29 | # release_0.0.4 30 | 31 | | 序号 | 变化 | 时间 | 说明 | 32 | | 1 | A | 2019-11-8 23:12:03 | 新增 init 相关实现 | 33 | | 2 | A | 2019-11-8 23:12:03 | 新增 destroy 相关实现 | 34 | 35 | # release_0.0.4 36 | 37 | | 序号 | 变化 | 时间 | 说明 | 38 | | 1 | A | 2019-11-8 23:12:03 | 新增 init 相关实现 | 39 | | 2 | A | 2019-11-8 23:12:03 | 新增 destroy 相关实现 | 40 | 41 | # release_0.0.5 42 | 43 | | 序号 | 变化 | 时间 | 说明 | 44 | | 1 | O | 2019-11-9 10:55:48 | 优化部分代码实现 | 45 | | 2 | A | 2019-11-9 10:55:48 | 添加 AdviceRespCode 相关,为后期处理打下基础 | 46 | 47 | # release_0.0.6 48 | 49 | | 序号 | 变化 | 时间 | 说明 | 50 | | 1 | A | 2019-11-9 10:55:48 | 添加构造器创建实例特性 | 51 | | 2 | A | 2019-11-9 10:55:48 | 添加 factory-method 创建实例特用 | 52 | 53 | # release_0.0.7 54 | 55 | | 序号 | 变化 | 时间 | 说明 | 56 | | 1 | A | 2019-11-10 18:55:48 | 添加 property 处理相关特性 | 57 | 58 | # release_0.0.8 59 | 60 | | 序号 | 变化 | 时间 | 说明 | 61 | | 1 | A | 2019-11-10 18:55:48 | 添加 Aware 各种生命周期通知管理 | 62 | 63 | # release_0.0.9 64 | 65 | | 序号 | 变化 | 时间 | 说明 | 66 | | 1 | A | 2019-11-10 18:55:48 | 添加 parent 继承 | 67 | 68 | # release_0.1.0 69 | 70 | | 序号 | 变化 | 时间 | 说明 | 71 | | 1 | A | 2019-11-10 18:55:48 | 添加循环依赖判断 | 72 | 73 | # release_0.1.1 74 | 75 | | 序号 | 变化 | 时间 | 说明 | 76 | | 1 | A | 2019-11-25 18:55:48 | `@Configuration` 注解支持 | 77 | 78 | # release_0.1.2 79 | 80 | | 序号 | 变化 | 时间 | 说明 | 81 | | 1 | A | 2019-11-26 18:55:48 | `@Bean` 注解支持 | 82 | 83 | # release_0.1.3 84 | 85 | | 序号 | 变化 | 时间 | 说明 | 86 | | 1 | A | 2019-11-26 18:55:48 | `@Lazy` 注解支持 | 87 | | 2 | A | 2019-11-26 18:55:48 | `@Scope` 注解支持 | 88 | 89 | # release_0.1.4 90 | 91 | | 序号 | 变化 | 时间 | 说明 | 92 | | 1 | A | 2019-11-26 19:55:48 | 添加 `@Bean` 注解与 `@Configuration` 之间的依赖关系 | 93 | | 2 | A | 2019-11-26 19:55:48 | 添加 `@Role` 注解 | 94 | | 3 | A | 2019-11-26 19:55:48 | 添加 `@Import` 注解 | 95 | 96 | # release_0.1.5 97 | 98 | | 序号 | 变化 | 时间 | 说明 | 99 | | 1 | A | 2019-11-27 19:55:48 | 添加 `@Bean` 构造器指定参数的支持 | 100 | | 2 | A | 2019-11-27 19:55:48 | 添加 `@Description` 构造器指定参数的支持 | 101 | 102 | # release_0.1.6 103 | 104 | | 序号 | 变化 | 时间 | 说明 | 105 | | 1 | A | 2019-11-28 19:55:48 | 添加 `@Autowired`,支持单个和集合字段注入 | 106 | 107 | # release_0.1.7 108 | 109 | | 序号 | 变化 | 时间 | 说明 | 110 | | 1 | A | 2019-11-28 19:55:48 | 添加 `@Primary`,支持指定 bean 的优先级 | 111 | 112 | # release_0.1.8 113 | 114 | | 序号 | 变化 | 时间 | 说明 | 115 | | 1 | O | 2019-11-29 19:55:48 | 优化 BeanFactory 中对象创建和 BeanDefinition 注册的部分代码 | 116 | | 2 | O | 2019-11-29 19:55:48 | 优化 Aware 相关代码 | 117 | | 3 | A | 2019-11-30 11:50:00 | 添加 `@Conditional` 相关条件支持 | 118 | 119 | # release_0.1.9 120 | 121 | | 序号 | 变化 | 时间 | 说明 | 122 | | 1 | A | 2019-11-29 19:55:48 | 新增 Environment 环境抽象类 | 123 | | 2 | A | 2019-11-29 19:55:48 | 新增 `Profile` 环境抽象类 | 124 | 125 | # release_0.1.10 126 | 127 | | 序号 | 变化 | 时间 | 说明 | 128 | | 1 | F | 2019-11-29 19:55:48 | 修复类型获取的 BUG | 129 | | 2 | A | 2019-11-29 19:55:48 | 新增 Environment 的自动注入支持 | 130 | 131 | # release_0.1.11 132 | 133 | | 序号 | 变化 | 时间 | 说明 | 134 | | 1 | A | 2019-12-1 16:20:11 | 新增 `@ComponentScan` 包扫描支持 | 135 | | 2 | A | 2019-12-1 16:20:11 | 新增 `@Serivce` 注解 | 136 | -------------------------------------------------------------------------------- /cgit.bat: -------------------------------------------------------------------------------- 1 | :: 用于提交当前变更(windows) 2 | :: author: houbb 3 | :: LastUpdateTime: 2018-11-22 09:08:52 4 | :: 用法:双击运行,或者当前路径 cmd 直接输入 .\cgit.bat 5 | 6 | git pull 7 | git add . 8 | git commit -m "[Feature] add for new" 9 | git push 10 | git status 11 | 12 | -------------------------------------------------------------------------------- /cgit.sh: -------------------------------------------------------------------------------- 1 | # 提交 2 | 3 | git pull 4 | git add . 5 | git commit -m "[Feature] add for new" 6 | git push 7 | git status 8 | 9 | # 1. 赋值权限: chmod +x ./cgit.sh 10 | # 2. 执行: ./cgit.sh 11 | # Last Update Time: 2018-11-21 21:55:38 12 | # Author: houbb -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/houbb/ioc/b67482c487fba3f1e8bedf13079333bed8cb9316/docs/README.md -------------------------------------------------------------------------------- /docs/issues/v0.0.1-beanFactory初始化.md: -------------------------------------------------------------------------------- 1 | # 特性 2 | 3 | 最基本的基于 json 配置实现的 BeanFactory。 4 | 5 | ## 无参构造函数 6 | 7 | # 属性的指定 8 | 9 | ## 构造器 10 | 11 | ## property setter 12 | 13 | ref 14 | 15 | value 16 | 17 | ## @Autowired 注解 18 | 19 | spring3 零配置注解实现Bean定义(包括JSR-250、JSR-330) 20 | 21 | # 支持更多的方法 22 | 23 | 直到和 BeanFactory 持平。 24 | 25 | ## contains 等等 26 | 27 | # 更多的特性 28 | 29 | ## 延迟加载 30 | 31 | ## 单例 多例 32 | 33 | ## init destroy 34 | 35 | # 基于注解的处理 36 | 37 | ## @Inject 38 | 39 | # 支持更多的配置类型 40 | 41 | ## 后续版本 42 | 43 | 支持丰富的配置类型 44 | 45 | ## xml 46 | 47 | ## json 48 | 49 | ## properties 50 | 51 | ## ymal 52 | 53 | ## java resource code 54 | 55 | -------------------------------------------------------------------------------- /docs/issues/v0.0.2-beanFactory-listableFactory.md: -------------------------------------------------------------------------------- 1 | # containsBean(name) 2 | 3 | # getType(name) 4 | 5 | # getBean(ClassType) 6 | 7 | 不存在,或者不唯一异常 8 | 9 | # 根据类型+名称获取 10 | 11 | ``` 12 | T getBean(String name, Class requiredType) throws BeansException; 13 | ``` 14 | 15 | # 类型是否匹配 16 | 17 | ```java 18 | boolean isTypeMatch(String name, Class typeToMatch) throws NoSuchBeanDefinitionException; 19 | ``` 20 | 21 | =================== listBeanFactory 可遍历的列表信息 22 | 23 | # getBeans(ClassType) 24 | 25 | 获取多个该类型的 bean 列表 26 | 27 | 个人感觉别名并不是必要的。 28 | 29 | # 后期可以和 `@Autowired("name")` 结合。 30 | 31 | # ListableBeanFactory 处理。 32 | 33 | # 代码结构优化 34 | 35 | ## Reader 36 | 37 | 针对 Json 的 38 | 39 | ## Resource 40 | 41 | 针对资源的读取 42 | 43 | 比如 String/InputStream 44 | 45 | 个人倾向于 InputStream,更具有广泛性。 46 | 47 | 因为所有的内容最后还是要转化为 InputStream 进行处理。 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/issues/v0.0.3-beanFactory-singleton-lazyInit.md: -------------------------------------------------------------------------------- 1 | # 属性指定 2 | 3 | # BeanFactory 管理判断。 4 | 5 | 属性的管理,和对象的创建。 6 | 7 | # 是否延迟加载 8 | 9 | 10 | # 单例-多例 11 | 12 | 13 | threadLocal 14 | 15 | -------------------------------------------------------------------------------- /docs/issues/v0.0.4-beanFactory-init-destroy-对象的初始化销毁方法.md: -------------------------------------------------------------------------------- 1 | # bean 2 | 3 | 相关属性。 4 | 5 | 不进行生命周期的管理,后期会拓展为生命周期的管理。 6 | 7 | # 生命周期的管理 8 | 9 | Aware 生命周期接口函数 10 | 11 | ## 初始化的时候,调用 init() 12 | 13 | 创建的时候进行处理。 14 | 15 | ## 销毁的时候,调用 destroy() 16 | 17 | 借助 hook 函数 18 | 19 | # 接口 20 | 21 | - 初始化 22 | 23 | - 销毁 24 | 25 | # 指定 26 | 27 | - initialize() 28 | 29 | - destroy(); 30 | 31 | # 注解 32 | 33 | 这个需要进行扫描包,然后基于注解。 34 | 35 | 初期暂时不作处理。 36 | 37 | JSR-330 38 | 39 | JSR-225 40 | 41 | -------------------------------------------------------------------------------- /docs/issues/v0.0.5-beanFactory-respcode-统一处理.md: -------------------------------------------------------------------------------- 1 | # 异常码的设计 2 | 3 | 在我看来,各种不同名称的异常比如 `ClassNotFoundException` 4 | 5 | 给人的提示是非常好的。 6 | 7 | 但是如果每一种异常,都创建一个异常,那么会创建大量的异常类,感觉也没必要。 8 | 9 | # -------------------------------------------------------------------------------- /docs/issues/v0.0.6-beanFactory-constructor-factoryMethod.md: -------------------------------------------------------------------------------- 1 | # 指定构造方法 2 | 3 | factory-method 4 | 5 | (1)必须静态 6 | 7 | (2)必须无参 8 | 9 | (3)必须返回对象示例 10 | 11 | 静态工厂类方法。 12 | 13 | # 构造器-constructor 14 | 15 | ## 指定方式 16 | 17 | index 18 | 19 | name 20 | 21 | type 22 | 23 | ## 值类型 24 | 25 | ref 26 | 27 | value 28 | 29 | -------------------------------------------------------------------------------- /docs/issues/v0.0.7-beanFactory-property-属性设置.md: -------------------------------------------------------------------------------- 1 | # setter 方法 2 | 3 | ## 指定方式 4 | 5 | property-name 6 | 7 | ## 值类型 8 | 9 | ref 10 | 11 | value 12 | 13 | # 通过 set 方法 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/issues/v0.0.8-life-cycle-aware.md: -------------------------------------------------------------------------------- 1 | https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#aware-list 2 | 3 | # 循环依赖检测。 4 | 5 | 基于有向图的检测。 6 | 7 | # Aware 8 | 9 | 声明这个 bean,然后判断其对应的接口信息。 10 | 11 | 进行统一的处理。 12 | 13 | ## BeanName 14 | 15 | ## Context 16 | 17 | # 核心接口 PostProcessor 18 | 19 | 该接口只是作为标志,本身没有任何方法。 20 | 21 | 下面都是其子类。 22 | 23 | ## BeanFactoryPostProcessor 24 | 25 | ## ApplicationContextProcessor 26 | 27 | ## ApplicationContextPostProcessor 28 | 29 | -------------------------------------------------------------------------------- /docs/issues/v0.0.9-parent-依赖继承.md: -------------------------------------------------------------------------------- 1 | # parent 2 | 3 | 指定需要继承的属性,可以获得其所有的属性。 4 | 5 | # BeanDefinition 6 | 7 | AbstractBeanDefinition 8 | 9 | GenericBeanDefinition 10 | 11 | RootBeanDefinition 12 | 13 | ChildBeanDefinition 14 | 15 | # Attr 相关的接口处理 16 | 17 | ## 新增 18 | 19 | remove 20 | 21 | contains 22 | 23 | keys 24 | 25 | copy 26 | 27 | -------------------------------------------------------------------------------- /docs/issues/v0.1.0-循环依赖问题.md: -------------------------------------------------------------------------------- 1 | # 循环依赖检测。 2 | 3 | 基于有向图的检测。 4 | 5 | # 循环依赖检测 6 | 7 | ## 有向图算法 8 | 9 | ## 直接利用引用递归 10 | 11 | 12 | # 直接利用引用递归 13 | 14 | 属于最简单,也最不需要思考的方式。 15 | 16 | 性能也比较差。 17 | 18 | ## ref 19 | 20 | 直接循环引用 21 | 22 | A=>B 23 | 24 | B=>A 25 | 26 | # 核心流程 27 | 28 | 获取每一个包含 ref 的对象的依赖链条。 29 | 30 | 1. 获取直接依赖 31 | 32 | beanName dependsOn() 依赖的列表 33 | 34 | (1)构建一个类,依赖了哪些 beans 35 | 36 | (2)构建一个类,被哪些 beans 依赖 37 | 38 | ``` 39 | // Guarantee initialization of beans that the current bean depends on. 40 | String[] dependsOn = mbd.getDependsOn(); 41 | if (dependsOn != null) { 42 | for (String dependsOnBean : dependsOn) { 43 | if (isDependent(beanName, dependsOnBean)) { 44 | throw new BeanCreationException(mbd.getResourceDescription(), beanName, 45 | "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); 46 | } 47 | registerDependentBean(dependsOnBean, beanName); 48 | getBean(dependsOnBean); 49 | } 50 | } 51 | 52 | 53 | protected boolean isDependent(String beanName, String dependentBeanName) { 54 | return isDependent(beanName, dependentBeanName, null); 55 | } 56 | 57 | private boolean isDependent(String beanName, String dependentBeanName, Set alreadySeen) { 58 | String canonicalName = canonicalName(beanName); 59 | if (alreadySeen != null && alreadySeen.contains(beanName)) { 60 | return false; 61 | } 62 | 63 | Set dependentBeans = this.dependentBeanMap.get(canonicalName); 64 | if (dependentBeans == null) { 65 | return false; 66 | } 67 | if (dependentBeans.contains(dependentBeanName)) { 68 | return true; 69 | } 70 | 71 | for (String transitiveDependency : dependentBeans) { 72 | if (alreadySeen == null) { 73 | alreadySeen = new HashSet(); 74 | } 75 | alreadySeen.add(beanName); 76 | if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { 77 | return true; 78 | } 79 | } 80 | return false; 81 | } 82 | ``` 83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /docs/issues/v0.1.1-annotation-@Configuration.md: -------------------------------------------------------------------------------- 1 | ## @Configuration 2 | 3 | - AnnotationApplicationContext 基于注解的处理上下文。 4 | 5 | 注解上下文 6 | 7 | 认为 @Component 是一个基类。 8 | 9 | - BeanNameGenerator 10 | 11 | 对象名称生成类 12 | 13 | -------------------------------------------------------------------------------- /docs/issues/v0.1.10-annotation-property-@Value.md: -------------------------------------------------------------------------------- 1 | # Environment 2 | 3 | 自动注入的实现。 4 | 5 | 构建对象 BeanDefinition 6 | 7 | Done 8 | 9 | # Property 10 | 11 | 属性配置文件 12 | 13 | ## @PropertyResource 14 | 15 | 指定配置引入 16 | 17 | ## @Value 18 | 19 | 值注解。 20 | 21 | `${XXX:}` 22 | -------------------------------------------------------------------------------- /docs/issues/v0.1.11-annotation-@Component-classfiles.md: -------------------------------------------------------------------------------- 1 | # @ComponentScan 2 | 3 | 扫包,仅仅支持文件。 4 | 5 | # @Component 注解类 6 | 7 | -------------------------------------------------------------------------------- /docs/issues/v0.1.19-annotation-@Component-jars.md: -------------------------------------------------------------------------------- 1 | # @ComponentScan 2 | 3 | 扫包,支持 jar 文件 -------------------------------------------------------------------------------- /docs/issues/v0.1.2-annotation-@Bean.md: -------------------------------------------------------------------------------- 1 | # @Bean 对象处理 2 | 3 | - value 名称 4 | 5 | - init 6 | 7 | - destroy -------------------------------------------------------------------------------- /docs/issues/v0.1.3-annotation-@Lazy-@Scope.md: -------------------------------------------------------------------------------- 1 | ## 生命周期 2 | 3 | @Lazy 4 | 5 | 是否 lazy 6 | 7 | @Scope 8 | 9 | 是否 scope 单例?多例? -------------------------------------------------------------------------------- /docs/issues/v0.1.4-annotation-@Role-@Import.md: -------------------------------------------------------------------------------- 1 | # Role 2 | 3 | 只是一个标注注解,无实际含义。 4 | 5 | # Import 6 | 7 | 导入其他配置类信息 8 | 9 | -------------------------------------------------------------------------------- /docs/issues/v0.1.5-annotation-@Bean-constructor-@Description.md: -------------------------------------------------------------------------------- 1 | # @Bean 对应的参数 2 | 3 | ## 指定方法参数 4 | 5 | 通过方法参数直接获取对应信息。 6 | 7 | 被视为 depends on 8 | 9 | ## 参数的唯一性 10 | 11 | 如果指定的对象存在多个怎么办? 12 | 13 | 类型+名称 14 | 15 | ```java 16 | 17 | ``` 18 | 19 | # @Description 描述 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /docs/issues/v0.1.6-annotation-@Autowired.md: -------------------------------------------------------------------------------- 1 | # Autowired 2 | 3 | ## 字段支持 4 | 5 | 為了簡單,只支持字段的自动注入。 6 | 7 | ## 依赖 8 | 9 | 如果依赖类中有这个注入信息,那么这个被注入的类就是对应的依赖。 10 | 11 | ## 唯一性 12 | 13 | 默认直接根据 type 获取即可,如果存在多个结果,则根据 value() 值直接获取。 14 | 15 | 如果未指定值,则直接报错。 16 | 17 | 指定值则以用户指定为准,根据指定值去唯一定位元素。 -------------------------------------------------------------------------------- /docs/issues/v0.1.7-annotation-@Primary.md: -------------------------------------------------------------------------------- 1 | # @Primary 2 | 3 | 当对应的注解有多个的时候,可以直接这么处理。 4 | 5 | ## 对象构建 6 | 7 | 首先实现这个,就是根据类型获取多个的时候,直接处理。 8 | 9 | # Autowired 10 | 11 | 也可以通过这个来处理。 12 | 13 | -------------------------------------------------------------------------------- /docs/issues/v0.1.8-annotation-@Condition.md: -------------------------------------------------------------------------------- 1 | # @Conditional 2 | 3 | ## 条件说明 4 | 5 | 当一个Bean假如需要被纳入spring管理,该Bean依赖的Bean,或者该Bean本身,是否就应该直接创建出来,还是有相关的限制? 6 | 7 | 答案是:只有满足条件,该Bean才应该创建。 8 | 9 | Spring Condition的作用,就是解决了根据不同的条件动态解析或者创建某些bean操作的方式,无需硬编码这些逻辑,直接使用这些标注就可以了。 10 | 11 | 条件注解是Spring4提供的一种bean加载特性,主要用于控制配置类和bean初始化条件。 12 | 13 | 在springBoot,springCloud 14 | 15 | 一系列框架底层源码中,条件注解的使用到处可见。 16 | 17 | ## 实现 18 | 19 | - 接口 20 | 21 | ```java 22 | boolean matches(ctx); 23 | ``` 24 | 25 | # 拓展注解 26 | 27 | ``` 28 | @ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean) 29 | @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean) 30 | @ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean) 31 | @ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean) 32 | @ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean) 33 | @ConditionalOnNotWebApplication(不是web应用) 34 | ``` 35 | -------------------------------------------------------------------------------- /docs/issues/v0.1.9-annotation-Env-@Profile.md: -------------------------------------------------------------------------------- 1 | # Env 2 | 3 | 环境的抽象。 4 | 5 | 6 | 7 | 8 | # spring 拓展 9 | 10 | - @Profile 11 | 12 | 环境 13 | 14 | test 15 | 16 | dev 17 | 18 | pre 19 | 20 | prod 21 | 22 | 这个可以作为测试案例拓展注解,可以在测试中验证该特性。 23 | 24 | ## springBoot 拓展 25 | 26 | ``` 27 | @ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean) 28 | @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean) 29 | @ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean) 30 | @ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean) 31 | @ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean) 32 | @ConditionalOnNotWebApplication(不是web应用) 33 | ``` 34 | -------------------------------------------------------------------------------- /docs/issues/v0.2.1-beanFactory-resource-reader优化实现.md: -------------------------------------------------------------------------------- 1 | # 属性设置 2 | 3 | 各种程度上都是 Bean 创建之后的一些属性丰富。 4 | 5 | 放在 initBean 之前。 6 | 7 | 属于属性设置部分。 -------------------------------------------------------------------------------- /docs/issues/v0.3.2-beanFactory-xml配置支持.md: -------------------------------------------------------------------------------- 1 | # xml 配置支持 2 | 3 | 可以考虑不支持 xsd 4 | 5 | # 手写 xml 解析框架 6 | 7 | xml 8 | 9 | ## 注解 10 | 11 | ## bean 转换 12 | 13 | 基于 dom 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/user/01-BeanFactory.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/user/02-ListableBeanFactory.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/houbb/ioc/b67482c487fba3f1e8bedf13079333bed8cb9316/docs/user/02-ListableBeanFactory.md -------------------------------------------------------------------------------- /release.bat: -------------------------------------------------------------------------------- 1 | :: 用于 release 当前项目(windows) 2 | :: author: houbb 3 | :: LastUpdateTime: 2018-1-22 09:08:52 4 | :: 用法:双击运行,或者当前路径 cmd 直接输入 release.bat 5 | 6 | :: 关闭回显 7 | @echo OFF 8 | 9 | ECHO "============================= RELEASE START..." 10 | 11 | :: 版本号信息(需要手动指定) 12 | :::: 旧版本名称 13 | SET version=0.1.11 14 | :::: 新版本名称 15 | SET newVersion=0.1.12 16 | :::: 组织名称 17 | SET groupName=com.github.houbb 18 | :::: 项目名称 19 | SET projectName=ioc 20 | 21 | :: release 项目版本 22 | :::: snapshot 版本号 23 | SET snapshot_version=%version%"-SNAPSHOT" 24 | :::: 新的版本号 25 | SET release_version=%version% 26 | 27 | call mvn versions:set -DgroupId=%groupName% -DartifactId=%projectName% -DoldVersion=%snapshot_version% -DnewVersion=%release_version% 28 | call mvn -N versions:update-child-modules 29 | call mvn versions:commit 30 | call echo "1. RELEASE %snapshot_version% TO %release_version% DONE." 31 | 32 | 33 | :: 推送到 github 34 | git add . 35 | git commit -m "release branch %version%" 36 | git push 37 | git status 38 | 39 | ECHO "2. PUSH TO GITHUB DONE." 40 | 41 | :: 推送到 maven 中央仓库 42 | call mvn clean deploy -P release 43 | ECHO "3 PUSH TO MVN CENTER DONE." 44 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "============================= RELEASE START..." 3 | 4 | ## 版本号信息(需要手动指定) 5 | version="0.0.1" 6 | newVersion="0.0.2" 7 | projectName="csv" 8 | 9 | # release 项目版本 10 | ## snapshot 版本号 11 | snapshot_version=${version}"-SNAPSHOT" 12 | ## 新的版本号 13 | release_version=${version} 14 | 15 | mvn versions:set -DgroupId=com.github.houbb -DartifactId=${projectName} -DoldVersion=${snapshot_version} -DnewVersion=${release_version} 16 | mvn -N versions:update-child-modules 17 | mvn versions:commit 18 | echo "1. RELEASE ${snapshot_version} TO ${release_version} DONE." 19 | 20 | 21 | # 推送到 github 22 | git add . 23 | git commit -m "release branch ${version}" 24 | git push 25 | git status 26 | 27 | echo "2. PUSH TO GITHUB DONE." 28 | 29 | 30 | # 推送到 maven 中央仓库 31 | mvn clean deploy -P release 32 | 33 | echo "3. PUSH TO MAVEN CENTER DONE." 34 | 35 | # 合并到 master 分支 36 | branchName="release_"${version} # 分支名称 37 | git checkout master 38 | git pull 39 | git checkout ${branchName} 40 | git rebase master 41 | git checkout master 42 | git merge ${branchName} 43 | git push 44 | 45 | echo "4. MERGE TO MASTER DONE." 46 | 47 | 48 | # 拉取新的分支 49 | newBranchName="release_"${newVersion} 50 | git branch ${newBranchName} 51 | git checkout ${newBranchName} 52 | git push --set-upstream origin ${newBranchName} 53 | 54 | echo "5. NEW BRANCH DONE." 55 | 56 | # 修改新分支的版本号 57 | ## snapshot 版本号 58 | snapshot_new_version=${newVersion}"-SNAPSHOT" 59 | mvn versions:set -DgroupId=com.github.houbb -DartifactId=${projectName} -DoldVersion=${release_version} -DnewVersion=${snapshot_new_version} 60 | mvn -N versions:update-child-modules 61 | mvn versions:commit 62 | 63 | git add . 64 | git commit -m "modify branch ${release_version} TO ${snapshot_new_version}" 65 | git push 66 | git status 67 | echo "6. MODIFY ${release_version} TO ${snapshot_new_version} DONE." 68 | 69 | echo "============================= RELEASE END..." 70 | 71 | 72 | # 使用方式: 73 | # 1. 赋值权限: chmod +x ./release.sh 74 | # 2. 执行: ./release.sh 75 | # Last Update Time: 2018-01-20 13:17:06 76 | # Author: houbb 77 | 78 | 79 | -------------------------------------------------------------------------------- /release_rm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | echo "============================= RELEASE START..." 3 | 4 | ## 版本号信息(需要手动指定) 5 | oldVersion="1.0.0" 6 | newVersion="1.0.0" 7 | projectName="csv" 8 | 9 | # 删除分支 10 | oldBranchName="release_"${oldVersion} 11 | git branch -d ${oldBranchName} 12 | git push origin --delete ${oldBranchName} 13 | 14 | echo "1. Branch remove success..." 15 | 16 | # 拉取新的分支 17 | newBranchName="release_"${newVersion} 18 | git branch ${newBranchName} 19 | git checkout ${newBranchName} 20 | git push --set-upstream origin ${newBranchName} 21 | 22 | echo "2. NEW BRANCH DONE." 23 | 24 | # 修改新分支的版本号 25 | ## snapshot 版本号 26 | snapshot_new_version=${newVersion}"-SNAPSHOT" 27 | mvn versions:set -DgroupId=com.github.houbb -DartifactId=${projectName} -DoldVersion=${release_version} -DnewVersion=${snapshot_new_version} 28 | mvn -N versions:update-child-modules 29 | mvn versions:commit 30 | 31 | git add . 32 | git commit -m "modify branch ${release_version} TO ${snapshot_new_version}" 33 | git push 34 | git status 35 | echo "3. MODIFY ${release_version} TO ${snapshot_new_version} DONE." 36 | 37 | echo "============================= BRANCH RE-CREATE END..." 38 | 39 | echo "============================= BRANCH LIST =============================" 40 | git branch -a 41 | 42 | # 使用方式: 43 | # 注意:本脚本用于删除分支,谨慎使用! 44 | # 1. 赋值权限: chmod +x ./release_rm.sh 45 | # 2. 执行: ./release_rm.sh 46 | # Last Update Time: 2018-06-21 11:10:42 47 | # Author: houbb -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Autowired.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定自动注入的方式 7 | * (1)放在普通字段直接返回单个结果 8 | * (2)如果放在集合上,则考虑将所有的接口对应的对象全部获取到。 9 | * 10 | * 为了便于后期维护,暂时不支持数组。 11 | * 12 | * @author binbin.hou 13 | * @since 0.1.6 14 | */ 15 | @Documented 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target({ElementType.FIELD}) 18 | public @interface Autowired { 19 | 20 | /** 21 | * 指定依赖名称 22 | * @return 指定依赖名称 23 | * @since 0.1.6 24 | */ 25 | String value() default ""; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Bean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定 Bean 信息 7 | * @author binbin.hou 8 | * @since 0.1.2 9 | * @see com.github.houbb.ioc.support.name.BeanNameStrategy 命名策略 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.METHOD}) 14 | public @interface Bean { 15 | 16 | /** 17 | * 组件名称 18 | * @return 组件名称 19 | * @since 0.1.2 20 | */ 21 | String value() default ""; 22 | 23 | /** 24 | * 初始化方法 25 | * @return 初始化方法 26 | * @since 0.1.2 27 | */ 28 | String initMethod() default ""; 29 | 30 | /** 31 | * 销毁方法 32 | * @return 销毁方法 33 | * @since 0.1.2 34 | */ 35 | String destroyMethod() default ""; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Component.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定 ioc 管理类属性 7 | * @author binbin.hou 8 | * @since 0.1.1 9 | * @see com.github.houbb.ioc.support.name.BeanNameStrategy 命名策略 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 14 | public @interface Component { 15 | 16 | /** 17 | * 组件名称 18 | * @return 组件名称 19 | * @since 0.1.1 20 | */ 21 | String value() default ""; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/ComponentScan.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import com.github.houbb.ioc.support.name.BeanNameStrategy; 4 | import com.github.houbb.ioc.support.name.impl.DefaultBeanNameStrategy; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * 用于扫描组件类 10 | * 11 | * @author binbin.hou 12 | * @since 0.1.11 13 | * @see com.github.houbb.ioc.support.name.BeanNameStrategy 命名策略 14 | * @see Component 组件注解 15 | * @see com.github.houbb.ioc.support.scanner.TypeFilter 类型过滤类 16 | */ 17 | @Documented 18 | @Retention(RetentionPolicy.RUNTIME) 19 | @Target({ElementType.TYPE}) 20 | public @interface ComponentScan { 21 | 22 | /** 23 | * 指定扫描包名称 24 | * @return 组件名称 25 | * @since 0.1.11 26 | */ 27 | String[] value(); 28 | 29 | /** 30 | * 排除的注解 31 | * @return 注解类列表 32 | * @since 0.1.11 33 | */ 34 | Class[] excludes() default {}; 35 | 36 | /** 37 | * 包含的注解 38 | * @return 注解类列表 39 | * @since 0.1.11 40 | */ 41 | Class[] includes() default {Component.class}; 42 | 43 | /** 44 | * 对象名称策略 45 | * @return 名称策略类 46 | * @since 0.1.11 47 | */ 48 | Class beanNameStrategy() default DefaultBeanNameStrategy.class; 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Conditional.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import com.github.houbb.ioc.support.condition.Condition; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 标识一个对象是否被初始化。 9 | * 10 | * (1)如果不符合条件,直接跳过该对象的所有信息及其注册。 11 | * (2)如果这个注解放在 {@link Configuration} 对应的类上,则该类及其所有子类都符合这个属性。 12 | * (3)如果这个注解放在方法上,则只有该方法才被赋予这个属性。 13 | * 方法级别的优先级高于类级别。 14 | * 15 | * @author binbin.hou 16 | * @since 0.1.8 17 | * @see Condition 条件接口 18 | */ 19 | @Documented 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 22 | public @interface Conditional { 23 | 24 | /** 25 | * 条件上下文对应的接口 26 | * @return 条件列表 27 | * @since 0.1.8 28 | */ 29 | Class value(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Configuration.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定 java 配置注解 7 | * @author binbin.hou 8 | * @since 0.1.1 9 | * @see com.github.houbb.ioc.support.name.BeanNameStrategy 命名策略 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target(ElementType.TYPE) 14 | @Component 15 | public @interface Configuration { 16 | 17 | /** 18 | * 组件名称 19 | * @return 组件名称 20 | * @since 0.1.1 21 | */ 22 | String value() default ""; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Description.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定信息 7 | * (1)暂时不做实际处理,仅供查阅使用。 8 | * @author binbin.hou 9 | * @since 0.1.5 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.METHOD}) 14 | public @interface Description { 15 | 16 | /** 17 | * 描述信息 18 | * @return 组件名称 19 | * @since 0.1.5 20 | */ 21 | String value() default ""; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/FactoryMethod.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定工厂方法的注解 7 | * @author binbin.hou 8 | * @since 0.0.6 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target(ElementType.METHOD) 13 | public @interface FactoryMethod { 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Import.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于导入配置信息 7 | * 8 | * @author binbin.hou 9 | * @since 0.1.4 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.TYPE}) 14 | public @interface Import { 15 | 16 | /** 17 | * 导入配置类信息 18 | * @return 配置类数组 19 | * @since 0.1.4 20 | */ 21 | Class[] value(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Lazy.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 是否延迟加载 7 | * @author binbin.hou 8 | * @since 0.1.3 9 | * @see com.github.houbb.ioc.support.name.BeanNameStrategy 命名策略 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.TYPE, ElementType.METHOD}) 14 | public @interface Lazy { 15 | 16 | /** 17 | * 是否延迟加载 18 | * @return 是否延迟加载 19 | * @since 0.1.3 20 | */ 21 | boolean value() default false; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Primary.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 注定优先级为最优先 7 | * @author binbin.hou 8 | * @since 0.1.7 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target({ElementType.TYPE, ElementType.METHOD}) 13 | public @interface Primary { 14 | } -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Profile.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import com.github.houbb.ioc.constant.ProfileConst; 4 | import com.github.houbb.ioc.support.condition.impl.ProfileCondition; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * 指定环境信息 10 | * 11 | * (1)可以指定在配置类上 {@link Configuration} 所有配置类即后期的 {@link Component} 组件类。 12 | * (2)可以放在配置类中 {@link Bean} 标注的方法中。 13 | * 14 | * 如果方法没有指定,则默认去当前类的环境信息。 15 | * 16 | * @author binbin.hou 17 | * @since 0.1.9 18 | */ 19 | @Documented 20 | @Retention(RetentionPolicy.RUNTIME) 21 | @Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 22 | @Conditional(ProfileCondition.class) 23 | public @interface Profile { 24 | 25 | /** 26 | * 指定环境信息 27 | * @return 指定环境信息 28 | * @see ProfileConst 环境常量 29 | * @since 0.1.9 30 | */ 31 | String[] value(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/PropertiesResource.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定配置文件路径 7 | * @author binbin.hou 8 | * @since 0.1.10 9 | * @see Value 值注解 10 | * @see Configuration 必须和配置注解共同使用才会使用(保证规范性) 11 | */ 12 | @Documented 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target({ElementType.TYPE}) 15 | public @interface PropertiesResource { 16 | 17 | /** 18 | * 配置文件路径列表 19 | * @return 指定依赖名称 20 | * @since 0.1.10 21 | */ 22 | String[] value(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Role.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定角色的信息 7 | * 8 | * 暂时不做该注解的处理,仅供使用参考。 9 | * @author binbin.hou 10 | * @since 0.1.4 11 | */ 12 | @Documented 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target({ElementType.METHOD, ElementType.TYPE}) 15 | public @interface Role { 16 | 17 | /** 18 | * 角色名称 19 | * @return 角色名称 20 | * @since 0.1.4 21 | */ 22 | String value() default ""; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Scope.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import com.github.houbb.ioc.constant.ScopeConst; 4 | 5 | import java.lang.annotation.*; 6 | 7 | /** 8 | * 用于指生命周期 scope 9 | * @author binbin.hou 10 | * @since 0.1.3 11 | * @see com.github.houbb.ioc.constant.enums.ScopeEnum 枚举 12 | */ 13 | @Documented 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.METHOD, ElementType.TYPE}) 16 | public @interface Scope { 17 | 18 | /** 19 | * 生命周期指定 20 | * @return 生命周期指定 21 | * @since 0.1.3 22 | * @see ScopeConst 常量 23 | */ 24 | String value() default ScopeConst.SINGLETON; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Service.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 用于指定 ioc 管理类属性 7 | * @author binbin.hou 8 | * @since 0.1.11 9 | * @see com.github.houbb.ioc.support.name.BeanNameStrategy 命名策略 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.TYPE}) 14 | @Component 15 | public @interface Service { 16 | 17 | /** 18 | * 服务类名称 19 | * @return 服务类名称 20 | * @since 0.1.11 21 | */ 22 | String value() default ""; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/Value.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 属性值指定 7 | * @author binbin.hou 8 | * @since 0.1.10 9 | */ 10 | @Documented 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target({ElementType.FIELD}) 13 | public @interface Value { 14 | 15 | /** 16 | * 属性值指定 17 | * (1)如果是 ${} 则进行占位符处理,如果不是则保持原样。 18 | * @return 指定依赖名称 19 | * @since 0.1.10 20 | */ 21 | String value(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/annotation/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 注解相关 3 | * @since 0.0.6 4 | */ 5 | package com.github.houbb.ioc.annotation; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/constant/AnnotationConst.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.constant; 2 | 3 | import com.github.houbb.ioc.annotation.Component; 4 | import com.github.houbb.ioc.annotation.Service; 5 | 6 | /** 7 | * 注解常量 8 | *

project: ioc-ScopeConst

9 | *

create on 2019/11/26 22:20

10 | * 11 | * @author Administrator 12 | * @since 0.1.11 13 | */ 14 | public final class AnnotationConst { 15 | 16 | /** 17 | * value() 名称 18 | * @since 0.1.11 19 | * @see Component#value() 20 | * @see Service#value() 21 | */ 22 | public static final String METHOD_VALUE = "value"; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/constant/ProfileConst.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.constant; 2 | 3 | /** 4 | * 环境常量 5 | *

project: ioc-ScopeConst

6 | *

create on 2019/11/26 22:20

7 | * 8 | * @author Administrator 9 | * @since 0.1.9 10 | */ 11 | public final class ProfileConst { 12 | 13 | /** 14 | * 默认 15 | * @since 0.1.9 16 | */ 17 | public static final String DEFAULT = "default"; 18 | 19 | /** 20 | * 开发环境 21 | * @since 0.1.9 22 | */ 23 | public static final String DEV = "dev"; 24 | 25 | /** 26 | * 测试环境 27 | * @since 0.1.9 28 | */ 29 | public static final String TEST = "test"; 30 | 31 | /** 32 | * 准生产环境 33 | * @since 0.1.9 34 | */ 35 | public static final String PRE_PROD = "preProd"; 36 | 37 | /** 38 | * 性能压测环境 39 | * @since 0.1.9 40 | */ 41 | public static final String PERFORMANCE = "performance"; 42 | 43 | /** 44 | * 生产环境 45 | * @since 0.1.9 46 | */ 47 | public static final String PROD = "prod"; 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/constant/ScopeConst.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.constant; 2 | 3 | /** 4 | *

project: ioc-ScopeConst

5 | *

create on 2019/11/26 22:20

6 | * 7 | * @author Administrator 8 | * @since 0.1.3 9 | */ 10 | public final class ScopeConst { 11 | 12 | /** 13 | * 单例 14 | * @since 0.1.3 15 | */ 16 | public static final String SINGLETON = "singleton"; 17 | 18 | /** 19 | * 多例 20 | * @since 0.1.3 21 | */ 22 | public static final String PROTOTYPE = "prototype"; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/constant/enums/BeanSourceTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.constant.enums; 2 | 3 | /** 4 | * 对象资源类型枚举 5 | * @author binbin.hou 6 | * @since 0.1.2 7 | */ 8 | public enum BeanSourceTypeEnum { 9 | 10 | /** 11 | * 通过资源文件配置 12 | * @since 0.1.2 13 | */ 14 | RESOURCE, 15 | 16 | /** 17 | * 配置注解类 18 | * @since 0.1.2 19 | */ 20 | CONFIGURATION, 21 | 22 | /** 23 | * 配置注解 bean 类 24 | * @since 0.1.2 25 | */ 26 | CONFIGURATION_BEAN, 27 | 28 | /** 29 | * 拓展支持类 30 | * @since 0.1.9 31 | */ 32 | SUPPORT, 33 | 34 | /** 35 | * 组件信息 36 | * @since 0.1.11 37 | */ 38 | COMPONENT 39 | ; 40 | 41 | /** 42 | * 是否为配置对象 43 | * @param sourceTypeEnum 数据类型枚举 44 | * @return 结果 45 | * @since 0.1.5 46 | */ 47 | public static boolean isConfigurationBean(final BeanSourceTypeEnum sourceTypeEnum) { 48 | return CONFIGURATION_BEAN.equals(sourceTypeEnum); 49 | } 50 | 51 | /** 52 | * 是否为配置 53 | * @param sourceTypeEnum 数据类型枚举 54 | * @return 结果 55 | * @since 0.1.10 56 | */ 57 | public static boolean isConfiguration(final BeanSourceTypeEnum sourceTypeEnum) { 58 | return CONFIGURATION.equals(sourceTypeEnum); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/constant/enums/ScopeEnum.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.constant.enums; 2 | 3 | import com.github.houbb.ioc.constant.ScopeConst; 4 | 5 | /** 6 | *

project: ioc-ScopeEnum

7 | *

create on 2019/11/8 20:19

8 | * 9 | * @author Administrator 10 | * @since 0.0.3 11 | */ 12 | public enum ScopeEnum { 13 | /** 14 | * 单例 15 | * @since 0.0.3 16 | */ 17 | SINGLETON(ScopeConst.SINGLETON), 18 | 19 | /** 20 | * 多例 21 | * @since 0.0.3 22 | */ 23 | PROTOTYPE(ScopeConst.PROTOTYPE), 24 | ; 25 | 26 | /** 27 | * 编码信息 28 | * @since 0.0.3 29 | */ 30 | private final String code; 31 | 32 | ScopeEnum(String code) { 33 | this.code = code; 34 | } 35 | 36 | public String getCode() { 37 | return code; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/constant/enums/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 枚举文件夹 3 | *

project: ioc-package-info

4 | *

create on 2019/11/8 20:19

5 | * 6 | * @author Administrator 7 | * @since 0.0.3 8 | */ 9 | package com.github.houbb.ioc.constant.enums; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/constant/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | *

project: ioc-package-info

3 | *

create on 2019/11/8 20:19

4 | * 5 | * @author Administrator 6 | * @since 0.0.3 7 | */ 8 | package com.github.houbb.ioc.constant; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/context/ApplicationContext.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.context; 2 | 3 | import com.github.houbb.heaven.util.lang.StringUtil; 4 | import com.github.houbb.ioc.core.ListableBeanFactory; 5 | import com.github.houbb.ioc.support.envrionment.EnvironmentCapable; 6 | 7 | /** 8 | * 应用上下文接口 9 | *

project: ioc-ApplicationContext

10 | *

create on 2019/11/8 22:25

11 | * 12 | * @author Administrator 13 | * @since 0.0.4 14 | */ 15 | public interface ApplicationContext extends ListableBeanFactory, EnvironmentCapable { 16 | 17 | /** 18 | * 获取应用名称 19 | * @return 应用名称 20 | * @since 0.0.4 21 | */ 22 | String getApplicationName(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/context/JsonApplicationContext.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.context; 2 | 3 | import com.github.houbb.heaven.util.io.FileUtil; 4 | import com.github.houbb.ioc.model.BeanDefinition; 5 | import com.github.houbb.json.bs.JsonBs; 6 | 7 | import java.io.InputStream; 8 | import java.util.List; 9 | 10 | /** 11 | * JSON 应用上下文 12 | * 13 | * 所有的 applicationContext 应该有一个完整的 14 | * 15 | * 读取文件:https://blog.csdn.net/feeltouch/article/details/83796764 16 | * @author binbin.hou 17 | * @since 0.0.1 18 | */ 19 | public class JsonApplicationContext extends AbstractApplicationContext { 20 | 21 | /** 22 | * 文件名称 23 | * @since 0.0.1 24 | */ 25 | private final String fileName; 26 | 27 | public JsonApplicationContext(String fileName) { 28 | this.fileName = fileName; 29 | 30 | super.init(); 31 | } 32 | 33 | /** 34 | * 构建对象属性列表 35 | * @return 对象属性列表 36 | * @since 0.0.4 37 | */ 38 | @Override 39 | protected List buildBeanDefinitionList() { 40 | //1. 读取配置信息 41 | InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); 42 | final String jsonConfig = FileUtil.getFileContent(is); 43 | 44 | //2. 配置信息转化为标准的 beanDefinition 45 | return JsonBs.deserializeArray(jsonConfig, BeanDefinition.class); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/context/package-info.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.context; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/core/BeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.core; 2 | 3 | /** 4 | * bean 工厂接口 5 | * @author binbin.hou 6 | * @since 0.0.1 7 | */ 8 | public interface BeanFactory { 9 | 10 | /** 11 | * 根据名称获取对应的实例信息 12 | * (1)属性不存在,抛出不存在异常 {@link com.github.houbb.ioc.exception.IocRuntimeException} 13 | * (2)存在多个对象实现,直接抛出异常 {@link com.github.houbb.ioc.exception.IocRuntimeException} 14 | * @param beanName bean 名称 15 | * @return 对象信息 16 | * @since 0.0.1 17 | */ 18 | Object getBean(final String beanName); 19 | 20 | /** 21 | * 获取指定类型的实现 22 | * @param beanName 属性名称 23 | * @param requiredType 类型 24 | * @param 泛型 25 | * @return 结果 26 | * @since 0.0.1 27 | */ 28 | T getBean(final String beanName, final Class requiredType); 29 | 30 | /** 31 | * 是否包含指定的 bean 32 | * @param beanName bean 名称 33 | * @return 是否包含 34 | * @since 0.0.2 35 | */ 36 | boolean containsBean(final String beanName); 37 | 38 | /** 39 | * 指定的 bean 和需要的类型二者是否匹配。 40 | * @param beanName bean 名称 41 | * @param requiredType 需要的类型 42 | * @return 是否包含 43 | * @since 0.0.2 44 | */ 45 | boolean isTypeMatch(final String beanName, final Class requiredType); 46 | 47 | /** 48 | * 获取 bean 对应的类型 49 | * @param beanName bean 名称 50 | * @return 类型信息 51 | * @since 0.0.2 52 | * @see #getBean(String) 对应的类型 53 | */ 54 | Class getType(final String beanName); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/core/ConfigableBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.core; 2 | 3 | /** 4 | * 可配置的 BeanFactory 接口 5 | * 6 | * (1)比如是否为单例/多例/获取对应的配置信息 7 | * (2)常见的其他属性,处理信息设置。 8 | * 9 | * @author binbin.hou 10 | * @since 0.0.7 11 | */ 12 | public interface ConfigableBeanFactory extends BeanFactory { 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/core/ListableBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.core; 2 | 3 | import java.util.List; 4 | import java.util.Set; 5 | 6 | /** 7 | * bean 工厂接口 8 | * @author binbin.hou 9 | * @since 0.0.1 10 | */ 11 | public interface ListableBeanFactory extends BeanFactory { 12 | 13 | /** 14 | * 获取指定类型的实现 15 | * (1)如果对应类型不存在,则直接抛出异常 16 | * (2)返回对应的列表信息 17 | * @param requiredType 类型 18 | * @param 泛型 19 | * @return bean 列表 20 | * @since 0.0.2 21 | */ 22 | List getBeans(final Class requiredType); 23 | 24 | /** 25 | * 根据类型获取对应的 bean 名称列表 26 | * @param requiredType 类型 27 | * @return 对应的列表 28 | * @since 0.1.5 29 | */ 30 | Set getBeanNames(final Class requiredType); 31 | 32 | /** 33 | * 获取指定类型的对象 34 | * @param requiredType 指定类型 35 | * @param beanName 属性名称,可能为空 36 | * @param 泛型 37 | * @return 结果 38 | * @since 0.1.6 39 | * @throws com.github.houbb.ioc.exception.IocRuntimeException 如果对应的信息不唯一 40 | * @see com.github.houbb.ioc.annotation.Primary 优先选择,如果当 beanName 为空时 41 | * @since 0.1.6 42 | */ 43 | T getRequiredTypeBean(final Class requiredType, final String beanName); 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/core/impl/DefaultBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.core.impl; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.lang.ObjectUtil; 5 | import com.github.houbb.ioc.constant.enums.ScopeEnum; 6 | import com.github.houbb.ioc.core.BeanFactory; 7 | import com.github.houbb.ioc.exception.IocRuntimeException; 8 | import com.github.houbb.ioc.model.BeanDefinition; 9 | import com.github.houbb.ioc.support.aware.service.AwareService; 10 | import com.github.houbb.ioc.support.aware.service.impl.DefaultAwareService; 11 | import com.github.houbb.ioc.support.cycle.DependsCheckService; 12 | import com.github.houbb.ioc.support.cycle.impl.DefaultDependsCheckService; 13 | import com.github.houbb.ioc.support.lifecycle.DisposableBean; 14 | import com.github.houbb.ioc.support.lifecycle.registry.BeanDefinitionRegistry; 15 | import com.github.houbb.ioc.support.lifecycle.registry.impl.DefaultBeanDefinitionRegistry; 16 | import com.github.houbb.ioc.support.lifecycle.service.BeanLifecycleService; 17 | import com.github.houbb.ioc.support.lifecycle.service.impl.DefaultBeanLifecycleService; 18 | 19 | /** 20 | * bean 工厂接口 21 | * 22 | * @author binbin.hou 23 | * @since 0.0.1 24 | */ 25 | public class DefaultBeanFactory implements BeanFactory, DisposableBean { 26 | 27 | /** 28 | * 依赖检测服务 29 | * 30 | * @since 0.1.0 31 | */ 32 | protected DependsCheckService dependsCheckService = new DefaultDependsCheckService(); 33 | 34 | /** 35 | * 对象信息注册 36 | * 37 | * @since 0.1.8 38 | */ 39 | protected BeanDefinitionRegistry beanDefinitionRegistry = new DefaultBeanDefinitionRegistry(); 40 | 41 | /** 42 | * 对象创建服务类 43 | * @since 0.1.8 44 | */ 45 | protected BeanLifecycleService beanLifecycleService = new DefaultBeanLifecycleService(); 46 | 47 | /** 48 | * 监听通知服务类 49 | * @since 0.1.8 50 | */ 51 | protected AwareService awareService = new DefaultAwareService(); 52 | 53 | public DefaultBeanFactory() { 54 | awareService.setBeanFactory(this); 55 | 56 | beanLifecycleService.setBeanFactory(this); 57 | beanLifecycleService.setDependsCheckService(this.dependsCheckService); 58 | } 59 | 60 | /** 61 | * 注册对象定义信息 62 | * 63 | * @param beanName 属性信息 64 | * @param beanDefinition 对象定义 65 | * @since 0.0.1 66 | */ 67 | protected void registerBeanDefinition(final String beanName, final BeanDefinition beanDefinition) { 68 | beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition); 69 | 70 | awareService.notifyAllBeanNameAware(beanName); 71 | } 72 | 73 | @Override 74 | public Object getBean(String beanName) { 75 | ArgUtil.notNull(beanName, "beanName"); 76 | // 获取对应配置信息 77 | BeanDefinition beanDefinition = beanDefinitionRegistry.getBeanDefinition(beanName); 78 | if (ObjectUtil.isNull(beanDefinition)) { 79 | throw new IocRuntimeException(beanName + " not exists in bean define."); 80 | } 81 | 82 | // 如果为多例,直接创建新的对象即可。 83 | final String scope = beanDefinition.getScope(); 84 | if (!ScopeEnum.SINGLETON.getCode().equals(scope)) { 85 | return beanLifecycleService.createBean(beanDefinition); 86 | } 87 | 88 | // 单例的流程 89 | return beanLifecycleService.registerSingletonBean(beanName, beanDefinition); 90 | } 91 | 92 | @Override 93 | @SuppressWarnings("unchecked") 94 | public T getBean(String beanName, Class requiredType) { 95 | ArgUtil.notNull(beanName, "beanName"); 96 | ArgUtil.notNull(requiredType, "requiredType"); 97 | 98 | Object object = getBean(beanName); 99 | return (T) object; 100 | } 101 | 102 | @Override 103 | public boolean containsBean(String beanName) { 104 | ArgUtil.notNull(beanName, "beanName"); 105 | return beanDefinitionRegistry.containsBeanDefinition(beanName); 106 | } 107 | 108 | @Override 109 | public boolean isTypeMatch(String beanName, Class requiredType) { 110 | ArgUtil.notNull(beanName, "beanName"); 111 | ArgUtil.notNull(requiredType, "requiredType"); 112 | 113 | Class beanType = getType(beanName); 114 | return requiredType.equals(beanType); 115 | } 116 | 117 | @Override 118 | public Class getType(String beanName) { 119 | ArgUtil.notNull(beanName, "beanName"); 120 | 121 | Object bean = this.getBean(beanName); 122 | return bean.getClass(); 123 | } 124 | 125 | @Override 126 | public void destroy() { 127 | } 128 | 129 | } 130 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/core/impl/DefaultListableBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.core.impl; 2 | 3 | import com.github.houbb.heaven.support.handler.IHandler; 4 | import com.github.houbb.heaven.util.guava.Guavas; 5 | import com.github.houbb.heaven.util.lang.ObjectUtil; 6 | import com.github.houbb.heaven.util.lang.StringUtil; 7 | import com.github.houbb.heaven.util.util.CollectionUtil; 8 | import com.github.houbb.heaven.util.util.SetUtil; 9 | import com.github.houbb.ioc.annotation.Primary; 10 | import com.github.houbb.ioc.core.ListableBeanFactory; 11 | import com.github.houbb.ioc.exception.IocRuntimeException; 12 | 13 | import java.util.List; 14 | import java.util.Set; 15 | 16 | /** 17 | * listable bean 工厂接口 18 | * @author binbin.hou 19 | * @since 0.0.2 20 | */ 21 | public class DefaultListableBeanFactory extends DefaultBeanFactory implements ListableBeanFactory { 22 | 23 | /** 24 | * 获取 beans 信息列表 25 | * 26 | * @param requiredType 指定类型 27 | * @param 泛型 28 | * @return 结果列表 29 | * @since 0.0.8 30 | * @throws IocRuntimeException 如果没有发现对应类 31 | */ 32 | @Override 33 | public List getBeans(final Class requiredType) { 34 | Set beanNames = beanDefinitionRegistry.getBeanNames(requiredType); 35 | if (CollectionUtil.isEmpty(beanNames)) { 36 | return Guavas.newArrayList(); 37 | } 38 | 39 | // 构建结果 40 | return CollectionUtil.toList(beanNames, new IHandler() { 41 | @Override 42 | public T handle(String name) { 43 | return getBean(name, requiredType); 44 | } 45 | }); 46 | } 47 | 48 | /** 49 | * 根据类型获取对应的属性名称 50 | * 51 | * @param requiredType 需求类型 52 | * @return bean 名称列表 53 | * @since 0.0.2 初始化 54 | * @since 0.1.5 设置为公开方法 55 | */ 56 | @Override 57 | public Set getBeanNames(Class requiredType) { 58 | return beanDefinitionRegistry.getBeanNames(requiredType); 59 | } 60 | 61 | @Override 62 | @SuppressWarnings("unchecked") 63 | public T getRequiredTypeBean(Class requiredType, String beanName) { 64 | Set beanNames = this.getBeanNames(requiredType); 65 | if (CollectionUtil.isEmpty(beanNames)) { 66 | throw new IocRuntimeException("RequiredType of " + requiredType.getName() + " beans not found!"); 67 | } 68 | if (beanNames.size() == 1) { 69 | final String firstBeanName = SetUtil.getFirst(beanNames); 70 | return (T) getBean(firstBeanName); 71 | } 72 | if (StringUtil.isNotEmpty(beanName)) { 73 | return (T) getBean(beanName); 74 | } 75 | 76 | //1. 获取 @Primary 对应的信息,不为空则返回。 77 | T primary = getPrimaryBean(requiredType); 78 | if(ObjectUtil.isNotNull(primary)) { 79 | return primary; 80 | } 81 | 82 | throw new IocRuntimeException("RequiredType of " + requiredType.getName() + " must be unique!"); 83 | } 84 | 85 | /** 86 | * 获取指定了 {@link com.github.houbb.ioc.annotation.Primary} 优先的对象 87 | * (1)优先返回第一个该注解指定的对象 88 | * (2)如果没有,则返回空。 89 | * 90 | * @param requiredType 需求类型 91 | * @param 泛型 92 | * @return 结果 93 | * @since 0.1.7 94 | */ 95 | protected T getPrimaryBean(Class requiredType) { 96 | List beans = this.getBeans(requiredType); 97 | if(CollectionUtil.isEmpty(beans)) { 98 | return null; 99 | } 100 | 101 | for(T bean : beans) { 102 | Class clazz = bean.getClass(); 103 | if(clazz.isAnnotationPresent(Primary.class)) { 104 | return bean; 105 | } 106 | } 107 | return null; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/exception/IocAdviceRuntimeException.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.exception; 2 | 3 | import com.github.houbb.heaven.response.respcode.AdviceRespCode; 4 | 5 | /** 6 | * IoC 包含建议的异常信息 7 | *

project: ioc-IocRuntimeException

8 | *

create on 2019/11/6 19:29

9 | * 10 | * @author Administrator 11 | * @since 0.0.5 12 | */ 13 | public class IocAdviceRuntimeException extends RuntimeException { 14 | 15 | /** 16 | * 包含建议的响应编码 17 | * @since 0.0.5 18 | */ 19 | private final AdviceRespCode adviceRespCode; 20 | 21 | public IocAdviceRuntimeException(AdviceRespCode adviceRespCode) { 22 | this.adviceRespCode = adviceRespCode; 23 | } 24 | 25 | public IocAdviceRuntimeException(String message, AdviceRespCode adviceRespCode) { 26 | super(message); 27 | this.adviceRespCode = adviceRespCode; 28 | } 29 | 30 | public IocAdviceRuntimeException(String message, Throwable cause, AdviceRespCode adviceRespCode) { 31 | super(message, cause); 32 | this.adviceRespCode = adviceRespCode; 33 | } 34 | 35 | public IocAdviceRuntimeException(Throwable cause, AdviceRespCode adviceRespCode) { 36 | super(cause); 37 | this.adviceRespCode = adviceRespCode; 38 | } 39 | 40 | public IocAdviceRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, AdviceRespCode adviceRespCode) { 41 | super(message, cause, enableSuppression, writableStackTrace); 42 | this.adviceRespCode = adviceRespCode; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/exception/IocRuntimeException.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.exception; 2 | 3 | /** 4 | *

project: ioc-IocRuntimeException

5 | *

create on 2019/11/6 19:29

6 | * 7 | * @author Administrator 8 | * @since 0.0.1 9 | */ 10 | public class IocRuntimeException extends RuntimeException { 11 | 12 | public IocRuntimeException() { 13 | } 14 | 15 | public IocRuntimeException(String message) { 16 | super(message); 17 | } 18 | 19 | public IocRuntimeException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | 23 | public IocRuntimeException(Throwable cause) { 24 | super(cause); 25 | } 26 | 27 | public IocRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 28 | super(message, cause, enableSuppression, writableStackTrace); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/exception/respcode/IocRespCode.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.exception.respcode; 2 | 3 | import com.github.houbb.heaven.response.respcode.AdviceRespCode; 4 | import com.github.houbb.heaven.response.respcode.RespCode; 5 | 6 | /** 7 | * IoC 响应编码 8 | * @author binbin.hou 9 | * @since 0.0.5 10 | */ 11 | public enum IocRespCode implements AdviceRespCode { 12 | ; 13 | 14 | /** 15 | * 编码 16 | * @since 0.1.38 17 | */ 18 | private final String code; 19 | 20 | /** 21 | * 消息 22 | * @since 0.1.38 23 | */ 24 | private final String msg; 25 | 26 | /** 27 | * 建议 28 | * @since 0.1.38 29 | */ 30 | private final String advice; 31 | 32 | IocRespCode(String code, String msg, String advice) { 33 | this.code = code; 34 | this.msg = msg; 35 | this.advice = advice; 36 | } 37 | 38 | 39 | IocRespCode(final RespCode respCode, String advice) { 40 | this.code = respCode.getCode(); 41 | this.msg = respCode.getMsg(); 42 | this.advice = advice; 43 | } 44 | 45 | @Override 46 | public String getAdvice() { 47 | return this.advice; 48 | } 49 | 50 | @Override 51 | public String getCode() { 52 | return this.code; 53 | } 54 | 55 | @Override 56 | public String getMsg() { 57 | return this.msg; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return "IocRespCode{" + 63 | "code='" + code + '\'' + 64 | ", msg='" + msg + '\'' + 65 | ", advice='" + advice + '\'' + 66 | '}'; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/AnnotationBeanDefinition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model; 2 | 3 | import com.github.houbb.ioc.support.envrionment.PropertySource; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 注解对象定义属性 9 | * @author binbin.hou 10 | * @since 0.1.2 11 | */ 12 | public interface AnnotationBeanDefinition extends BeanDefinition { 13 | 14 | /** 15 | * 设置配置对象名称 16 | * @param configurationName 配置对象名称 17 | * @since 0.1.2 18 | */ 19 | void setConfigurationName(final String configurationName); 20 | 21 | /** 22 | * 获取配置名称 23 | * @return 配置名称 24 | * @since 0.1.2 25 | */ 26 | String getConfigurationName(); 27 | 28 | /** 29 | * 设置新建实例方法名称 30 | * @param configurationBeanMethod 方法名称 31 | * @since 0.1.2 32 | * @see java.lang.reflect.Method#invoke(Object, Object...) 反射创建实例 33 | */ 34 | void setConfigurationBeanMethod(final String configurationBeanMethod); 35 | 36 | /** 37 | * 获取新建实例方法名称 38 | * @return 方法名称 39 | * @since 0.1.2 40 | */ 41 | String getConfigurationBeanMethod(); 42 | 43 | /** 44 | * 设置对象方法参数类型列表 45 | * @param classes 参数类型列表 46 | * @since 0.1.5 47 | */ 48 | void setConfigBeanMethodParamTypes(final Class[] classes); 49 | 50 | /** 51 | * 获取对象方法参数类型列表 52 | * @return 参数类型列表 53 | * @since 0.1.5 54 | */ 55 | Class[] getConfigBeanMethodParamTypes(); 56 | 57 | /** 58 | * 设置参数依赖的对象列表 59 | * @param refs 依赖对象 60 | * @since 0.1.5 61 | */ 62 | void setConfigBeanMethodParamRefs(final List refs); 63 | 64 | /** 65 | * 获取参数依赖的对象列表 66 | * @since 0.1.5 67 | * @return 依赖的对象列表 68 | */ 69 | List getConfigBeanMethodParamRefs(); 70 | 71 | /** 72 | * 是否为主要 73 | * @return 是否为主要 74 | * @since 0.1.7 75 | */ 76 | boolean isPrimary(); 77 | 78 | /** 79 | * 设置 primary 80 | * @param primary 主要信息 81 | * @since 0.1.7 82 | */ 83 | void setPrimary(boolean primary); 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/BeanDefinition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model; 2 | 3 | import com.github.houbb.ioc.constant.enums.BeanSourceTypeEnum; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 对象定义属性 9 | * @author binbin.hou 10 | * @since 0.0.1 11 | */ 12 | public interface BeanDefinition { 13 | 14 | /** 15 | * 名称 16 | * @return 名称 17 | * @since 0.0.1 18 | */ 19 | String getName(); 20 | 21 | /** 22 | * 设置名称 23 | * @param name 名称 24 | * @since 0.0.1 25 | */ 26 | void setName(final String name); 27 | 28 | /** 29 | * 类名称 30 | * @return 类名称 31 | * @since 0.0.1 32 | */ 33 | String getClassName(); 34 | 35 | /** 36 | * 设置类名称 37 | * @param className 类名称 38 | * @since 0.0.1 39 | */ 40 | void setClassName(final String className); 41 | 42 | /** 43 | * 获取生命周期 44 | * @return 获取生命周期 45 | * @since 0.0.3 46 | */ 47 | String getScope(); 48 | 49 | /** 50 | * 设置是否单例 51 | * @param scope 是否单例 52 | * @since 0.0.3 53 | */ 54 | void setScope(final String scope); 55 | 56 | /** 57 | * 是否为延迟加载 58 | * @return 是否 59 | * @since 0.0.3 60 | */ 61 | boolean isLazyInit(); 62 | 63 | /** 64 | * 设置是否为延迟加载 65 | * @param isLazyInit 是否为延迟加载 66 | * @since 0.0.3 67 | */ 68 | void setLazyInit(final boolean isLazyInit); 69 | 70 | /** 71 | * 设置初始化方法 72 | * @param initialize 初始化方法名称 73 | * @since 0.0.4 74 | */ 75 | void setInitialize(final String initialize); 76 | 77 | /** 78 | * 获取初始化方法 79 | * @return 初始化方法 80 | * @since 0.0.4 81 | */ 82 | String getInitialize(); 83 | 84 | /** 85 | * 设置销毁方法 86 | * @param destroy 销毁方法名称 87 | * @since 0.0.4 88 | */ 89 | void setDestroy(final String destroy); 90 | 91 | /** 92 | * 获取销毁方法 93 | * @return 销毁 94 | * @since 0.0.4 95 | */ 96 | String getDestroy(); 97 | 98 | /** 99 | * 工厂类方法 100 | * @param factoryMethod 工厂类方法 101 | * @since 0.0.6 102 | */ 103 | void setFactoryMethod(final String factoryMethod); 104 | 105 | /** 106 | * 获取工厂类方法名称 107 | * @return 工厂类方法名称 108 | * @since 0.0.6 109 | */ 110 | String getFactoryMethod(); 111 | 112 | /** 113 | * 构造器参数列表 114 | * @return 构造器参数列表 115 | * @since 0.0.6 116 | */ 117 | List getConstructorArgList(); 118 | 119 | /** 120 | * 设置构造器参数定义列表 121 | * @param constructorArgList 构造器参数列表 122 | * @since 0.0.6 123 | */ 124 | void setConstructorArgList(final List constructorArgList); 125 | 126 | /** 127 | * 属性参数列表 128 | * @return 属性器参数列表 129 | * @since 0.0.7 130 | */ 131 | List getPropertyArgList(); 132 | 133 | /** 134 | * 设置属性参数定义列表 135 | * @param propertyArgList 属性参数列表 136 | * @since 0.0.7 137 | */ 138 | void setPropertyArgList(final List propertyArgList); 139 | 140 | /** 141 | * 是否为抽象类 142 | * @return 是否 143 | * @since 0.0.9 144 | */ 145 | boolean isAbstractClass(); 146 | 147 | /** 148 | * 设置是否为抽象类 149 | * @param abstractClass 是否 150 | * @since 0.0.9 151 | */ 152 | void setAbstractClass(boolean abstractClass); 153 | 154 | /** 155 | * 获取父类名称 156 | * @return 父类名称 157 | * @since 0.0.9 158 | */ 159 | String getParentName(); 160 | 161 | /** 162 | * 设置父类名称 163 | * @param parentName 父类名称 164 | * @since 0.0.9 165 | */ 166 | void setParentName(String parentName); 167 | 168 | /** 169 | * 设置对象数据来源 170 | * @param beanSourceType 对象数据来源 171 | * @since 0.1.2 172 | */ 173 | void setBeanSourceType(final BeanSourceTypeEnum beanSourceType); 174 | 175 | /** 176 | * 获取对象数据来源 177 | * @return 数据来源 178 | * @since 0.1.2 179 | */ 180 | BeanSourceTypeEnum getBeanSourceType(); 181 | 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/ConstructorArgDefinition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model; 2 | 3 | /** 4 | * 构造器参数定义信息 5 | * 6 | * 这里看起来只是一些属性的处理,实际上必须要面对两个核心的问题: 7 | * 8 | * (1)String value 与指定参数类型之间的转换,可以抽象为接口。 9 | * 内置各种默认的实现方式 10 | * 11 | * (2)Ref 当一旦指定了这个值之后,就需要处理一个依赖关系。 12 | * 必须将这个依赖联调处理好。 13 | * 14 | * 【注解的参数下标】 15 | * (1)如果用户不指定,则按照指定的顺序从0开始递增 16 | * (2)所以这里使用对象,而不是 int 类型,就是为了避免反序列化等处理,无法区分开是否为用户指定信息。 17 | * (3)这个必须断言为不可重复。 18 | * 19 | * 个人感觉这样不合理,所以直接移除这个指定 index 的特性。 20 | * 同理 name 可能会比较方便,但是需要做一次映射处理,暂时不做支持。 21 | * 22 | * @author binbin.hou 23 | * @since 0.0.6 24 | */ 25 | public interface ConstructorArgDefinition { 26 | 27 | /** 28 | * 参数类型全称 29 | * @return 类型全称 30 | * @since 0.0.6 31 | */ 32 | String getType(); 33 | 34 | /** 35 | * 设置参数类型全称 36 | * @param type 参数类型全称 37 | * @since 0.0.6 38 | */ 39 | void setType(final String type); 40 | 41 | /** 42 | * 值信息 43 | * @return 值信息 44 | * @since 0.0.6 45 | */ 46 | String getValue(); 47 | 48 | /** 49 | * 设置值 50 | * @param value 值 51 | * @since 0.0.6 52 | */ 53 | void setValue(final String value); 54 | 55 | /** 56 | * 获取引用的名称 57 | * @return 引用的例子名称 58 | * @since 0.0.6 59 | */ 60 | String getRef(); 61 | 62 | /** 63 | * 设置引用属性名称 64 | * @param ref 引用属性名称 65 | * @since 0.0.6 66 | */ 67 | void setRef(final String ref); 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/PropertyArgDefinition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model; 2 | 3 | /** 4 | * 属性参数定义 5 | * 6 | * @author binbin.hou 7 | * @since 0.0.7 8 | */ 9 | public interface PropertyArgDefinition { 10 | 11 | /** 12 | * 属性名称 13 | * @return 属性名称 14 | * @since 0.0.7 15 | */ 16 | String getName(); 17 | 18 | /** 19 | * 设置属性名称 20 | * @param name 属性名称 21 | * @since 0.0.7 22 | */ 23 | void setName(final String name); 24 | 25 | /** 26 | * 参数类型全称 27 | * @return 类型全称 28 | * @since 0.0.7 29 | */ 30 | String getType(); 31 | 32 | /** 33 | * 设置参数类型全称 34 | * @param type 参数类型全称 35 | * @since 0.0.7 36 | */ 37 | void setType(final String type); 38 | 39 | /** 40 | * 值信息 41 | * @return 值信息 42 | * @since 0.0.7 43 | */ 44 | String getValue(); 45 | 46 | /** 47 | * 设置值 48 | * @param value 值 49 | * @since 0.0.7 50 | */ 51 | void setValue(final String value); 52 | 53 | /** 54 | * 获取引用的名称 55 | * @return 引用的例子名称 56 | * @since 0.0.7 57 | */ 58 | String getRef(); 59 | 60 | /** 61 | * 设置引用属性名称 62 | * @param ref 引用属性名称 63 | * @since 0.0.7 64 | */ 65 | void setRef(final String ref); 66 | 67 | /** 68 | * 是否基于字段 69 | * @return 基于字段 70 | * @since 0.1.10 71 | */ 72 | boolean isFieldBase(); 73 | 74 | /** 75 | * 设置是否基于字段 76 | * @param fieldBase 基于字段 77 | * @since 0.1.10 78 | */ 79 | void setFieldBase(final boolean fieldBase); 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/impl/DefaultAnnotationBeanDefinition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.impl; 2 | 3 | import com.github.houbb.ioc.model.AnnotationBeanDefinition; 4 | import com.github.houbb.ioc.support.envrionment.PropertySource; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 默认注解对象定义属性 10 | * @author binbin.hou 11 | * @since 0.1.2 12 | */ 13 | public class DefaultAnnotationBeanDefinition extends DefaultBeanDefinition implements AnnotationBeanDefinition { 14 | 15 | /** 16 | * 配置信息名称 17 | * @since 0.1.2 18 | */ 19 | private String configurationName; 20 | 21 | /** 22 | * 配置信息对象名称 23 | * @since 0.1.2 24 | */ 25 | private String configurationBeanMethod; 26 | 27 | /** 28 | * 配置对象方法参数类型 29 | * @since 0.1.5 30 | */ 31 | private Class[] configBeanMethodParamTypes; 32 | 33 | /** 34 | * 配置对象方法参数引用 35 | * @since 0.1.5 36 | */ 37 | private List configBeanMethodParamRefs; 38 | 39 | /** 40 | * 是否为主要的对象 41 | * @since 0.1.7 42 | */ 43 | private boolean primary; 44 | 45 | @Override 46 | public String getConfigurationName() { 47 | return configurationName; 48 | } 49 | 50 | @Override 51 | public void setConfigurationName(String configurationName) { 52 | this.configurationName = configurationName; 53 | } 54 | 55 | @Override 56 | public String getConfigurationBeanMethod() { 57 | return configurationBeanMethod; 58 | } 59 | 60 | @Override 61 | public void setConfigurationBeanMethod(String configurationBeanMethod) { 62 | this.configurationBeanMethod = configurationBeanMethod; 63 | } 64 | 65 | @Override 66 | public Class[] getConfigBeanMethodParamTypes() { 67 | return configBeanMethodParamTypes; 68 | } 69 | 70 | @Override 71 | public void setConfigBeanMethodParamTypes(Class[] configBeanMethodParamTypes) { 72 | this.configBeanMethodParamTypes = configBeanMethodParamTypes; 73 | } 74 | 75 | @Override 76 | public List getConfigBeanMethodParamRefs() { 77 | return configBeanMethodParamRefs; 78 | } 79 | 80 | @Override 81 | public void setConfigBeanMethodParamRefs(List configBeanMethodParamRefs) { 82 | this.configBeanMethodParamRefs = configBeanMethodParamRefs; 83 | } 84 | 85 | @Override 86 | public boolean isPrimary() { 87 | return primary; 88 | } 89 | 90 | @Override 91 | public void setPrimary(boolean primary) { 92 | this.primary = primary; 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/impl/DefaultConstructorArgDefinition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.impl; 2 | 3 | import com.github.houbb.ioc.model.ConstructorArgDefinition; 4 | 5 | /** 6 | * 构造器参数定义信息 7 | * @author binbin.hou 8 | * @since 0.0.6 9 | */ 10 | public class DefaultConstructorArgDefinition implements ConstructorArgDefinition { 11 | 12 | /** 13 | * 类型 14 | * @since 0.0.6 15 | */ 16 | private String type; 17 | 18 | /** 19 | * 参数值 20 | * @since 0.0.6 21 | */ 22 | private String value; 23 | 24 | /** 25 | * 引用名称 26 | * @since 0.0.6 27 | */ 28 | private String ref; 29 | 30 | @Override 31 | public String getType() { 32 | return type; 33 | } 34 | 35 | @Override 36 | public void setType(String type) { 37 | this.type = type; 38 | } 39 | 40 | @Override 41 | public String getValue() { 42 | return value; 43 | } 44 | 45 | @Override 46 | public void setValue(String value) { 47 | this.value = value; 48 | } 49 | 50 | @Override 51 | public String getRef() { 52 | return ref; 53 | } 54 | 55 | @Override 56 | public void setRef(String ref) { 57 | this.ref = ref; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return "DefaultConstructorArgDefinition{" + 63 | "type='" + type + '\'' + 64 | ", value='" + value + '\'' + 65 | ", ref='" + ref + '\'' + 66 | '}'; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/impl/DefaultPropertyArgDefinition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.impl; 2 | 3 | import com.github.houbb.ioc.model.PropertyArgDefinition; 4 | 5 | /** 6 | * 默认属性属性参数 7 | * 8 | * @author binbin.hou 9 | * @since 0.0.7 10 | */ 11 | public class DefaultPropertyArgDefinition implements PropertyArgDefinition { 12 | 13 | /** 14 | * 属性名称 15 | * @since 0.0.7 16 | */ 17 | private String name; 18 | 19 | /** 20 | * 类型 21 | * @since 0.0.7 22 | */ 23 | private String type; 24 | 25 | /** 26 | * 参数值 27 | * @since 0.0.7 28 | */ 29 | private String value; 30 | 31 | /** 32 | * 引用名称 33 | * @since 0.0.7 34 | */ 35 | private String ref; 36 | 37 | /** 38 | * 是否基于字段 39 | * @since 0.1.10 40 | */ 41 | private boolean fieldBase; 42 | 43 | @Override 44 | public String getName() { 45 | return name; 46 | } 47 | 48 | @Override 49 | public void setName(String name) { 50 | this.name = name; 51 | } 52 | 53 | @Override 54 | public String getType() { 55 | return type; 56 | } 57 | 58 | @Override 59 | public void setType(String type) { 60 | this.type = type; 61 | } 62 | 63 | @Override 64 | public String getValue() { 65 | return value; 66 | } 67 | 68 | @Override 69 | public void setValue(String value) { 70 | this.value = value; 71 | } 72 | 73 | @Override 74 | public String getRef() { 75 | return ref; 76 | } 77 | 78 | @Override 79 | public void setRef(String ref) { 80 | this.ref = ref; 81 | } 82 | 83 | @Override 84 | public boolean isFieldBase() { 85 | return fieldBase; 86 | } 87 | 88 | @Override 89 | public void setFieldBase(boolean fieldBase) { 90 | this.fieldBase = fieldBase; 91 | } 92 | 93 | @Override 94 | public String toString() { 95 | return "DefaultPropertyArgDefinition{" + 96 | "name='" + name + '\'' + 97 | ", type='" + type + '\'' + 98 | ", value='" + value + '\'' + 99 | ", ref='" + ref + '\'' + 100 | ", fieldBase=" + fieldBase + 101 | '}'; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/AnnotationMeta.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.meta; 2 | 3 | /** 4 | * 注解元数据 5 | * @author binbin.hou 6 | * @since 0.1.6 7 | */ 8 | public interface AnnotationMeta extends BaseMeta { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/BaseAnnotationMeta.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.meta; 2 | 3 | import com.github.houbb.heaven.annotation.CommonEager; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 基础元数据 9 | * @author binbin.hou 10 | * @since 0.1.6 11 | */ 12 | @CommonEager 13 | public interface BaseAnnotationMeta extends BaseMeta { 14 | 15 | /** 16 | * 获取注解信息 17 | * @return 注解元信息列表 18 | * @since 0.1.6 19 | */ 20 | List getAnnotationMetas(); 21 | 22 | /** 23 | * 设置注解元数据 24 | * @param annotationMetas 注解元信息 25 | * @since 0.1.6 26 | */ 27 | void setAnnotationMetas(final List annotationMetas); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/BaseMeta.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.meta; 2 | 3 | import com.github.houbb.heaven.annotation.CommonEager; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 基础元数据 9 | * @author binbin.hou 10 | * @since 0.1.6 11 | */ 12 | @CommonEager 13 | public interface BaseMeta { 14 | 15 | /** 16 | * 获取 class 信息 17 | * @return 类信息 18 | * @since 0.1.6 19 | */ 20 | Class getClasss(); 21 | 22 | /** 23 | * 设置 class 信息 24 | * @param clazz 类信息 25 | * @since 0.1.6 26 | */ 27 | void setClass(final Class clazz); 28 | 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/ClassMeta.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.meta; 2 | 3 | import com.github.houbb.heaven.annotation.CommonEager; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 类元数据 9 | * @author binbin.hou 10 | * @since 0.1.6 11 | */ 12 | @CommonEager 13 | public interface ClassMeta extends BaseMeta { 14 | 15 | /** 16 | * 获取字段元信息列表 17 | * @return 字段列表 18 | * @since 0.1.6 19 | */ 20 | List getFieldMetas(); 21 | 22 | /** 23 | * 设置字段元信息 24 | * @param fieldMetas 字段元信息 25 | * @since 0.1.6 26 | */ 27 | void setFieldMetas(final List fieldMetas); 28 | 29 | /** 30 | * 获取方法元信息 31 | * @return 方法元信息 32 | * @since 0.1.6 33 | */ 34 | List getMethodMetas(); 35 | 36 | /** 37 | * 设置方法元信息 38 | * @param methodMetas 方法元信息 39 | * @since 0.1.6 40 | */ 41 | void setMethodMetas(final List methodMetas); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/FieldMeta.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.meta; 2 | 3 | /** 4 | * 字段元数据 5 | * @author binbin.hou 6 | * @since 0.1.6 7 | */ 8 | public interface FieldMeta extends BaseMeta { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/MethodMeta.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.meta; 2 | 3 | /** 4 | * 方法元数据 5 | * @author binbin.hou 6 | * @since 0.1.6 7 | */ 8 | public interface MethodMeta { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/ParamMeta.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model.meta; 2 | 3 | /** 4 | * 参数元数据 5 | * @author binbin.hou 6 | * @since 0.1.6 7 | */ 8 | public interface ParamMeta { 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/meta/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 元数据 3 | * 4 | * 这里只是尝试,建议全部使用字符串和基本类型。 5 | * 6 | * @since 0.1.6 7 | */ 8 | package com.github.houbb.ioc.model.meta; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/model/package-info.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.model; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/package-info.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/annotation/Lazys.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.annotation; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.lang.StringUtil; 5 | import com.github.houbb.ioc.annotation.Lazy; 6 | import com.github.houbb.ioc.annotation.Scope; 7 | 8 | import java.lang.reflect.Method; 9 | 10 | /** 11 | *

project: ioc-Scopes

12 | *

create on 2019/11/26 22:25

13 | * 14 | * @author Administrator 15 | * @since 0.1.3 16 | */ 17 | public final class Lazys { 18 | 19 | private Lazys(){} 20 | 21 | /** 22 | * 获取指定类的 Lazy 信息 23 | * 后期可以支持自定义注解,包含元注解 {@link com.github.houbb.ioc.annotation.Lazy} 即可。 24 | * @param clazz 类型 25 | * @return Lazy 信息 26 | * @since 0.1.3 27 | */ 28 | public static boolean getLazy(final Class clazz) { 29 | ArgUtil.notNull(clazz, "clazz"); 30 | 31 | if(clazz.isAnnotationPresent(Lazy.class)) { 32 | Lazy lazy = (Lazy) clazz.getAnnotation(Lazy.class); 33 | return lazy.value(); 34 | } 35 | return false; 36 | } 37 | 38 | /** 39 | * 获取指定方法的 scope 信息 40 | * 后期可以支持自定义注解,包含元注解 {@link com.github.houbb.ioc.annotation.Lazy} 即可。 41 | * 42 | * @param method 方法信息 43 | * @return scope 信息 44 | * @since 0.1.3 45 | */ 46 | public static boolean getLazy(final Method method) { 47 | ArgUtil.notNull(method, "method"); 48 | 49 | if(method.isAnnotationPresent(Lazy.class)) { 50 | Lazy lazy = (Lazy) method.getAnnotation(Lazy.class); 51 | return lazy.value(); 52 | } 53 | return false; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/annotation/Scopes.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.annotation; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.ioc.annotation.Scope; 5 | import com.github.houbb.ioc.constant.ScopeConst; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | *

project: ioc-Scopes

11 | *

create on 2019/11/26 22:25

12 | * 13 | * @author Administrator 14 | * @since 0.1.3 15 | */ 16 | public final class Scopes { 17 | 18 | private Scopes(){} 19 | 20 | /** 21 | * 获取指定类的 scope 信息 22 | * 后期可以支持自定义注解,包含元注解 {@link com.github.houbb.ioc.annotation.Scope} 即可。 23 | * @param clazz 类型 24 | * @return scope 信息 25 | * @since 0.1.3 26 | */ 27 | public static String getScope(final Class clazz) { 28 | ArgUtil.notNull(clazz, "clazz"); 29 | 30 | if(clazz.isAnnotationPresent(Scope.class)) { 31 | Scope scope = (Scope) clazz.getAnnotation(Scope.class); 32 | return scope.value(); 33 | } 34 | return ScopeConst.SINGLETON; 35 | } 36 | 37 | /** 38 | * 获取指定方法的 scope 信息 39 | * 后期可以支持自定义注解,包含元注解 {@link com.github.houbb.ioc.annotation.Scope} 即可。 40 | * @param method 方法信息 41 | * @return scope 信息 42 | * @since 0.1.3 43 | */ 44 | public static String getScope(final Method method) { 45 | ArgUtil.notNull(method, "method"); 46 | 47 | if(method.isAnnotationPresent(Scope.class)) { 48 | Scope scope = (Scope) method.getAnnotation(Scope.class); 49 | return scope.value(); 50 | } 51 | return ScopeConst.SINGLETON; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/annotation/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 相比较于 spring,单个注解的处理反而不够高明。 3 | * 4 | * 比较好的方式是针对每一个注解,都再次抽象为基本信息。 5 | * 6 | *

project: ioc-package-info

7 | *

create on 2019/11/26 22:25

8 | * 9 | * @author Administrator 10 | * @since 0.1.3 11 | */ 12 | package com.github.houbb.ioc.support.annotation; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/aware/ApplicationContextAware.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.aware; 2 | 3 | import com.github.houbb.ioc.context.ApplicationContext; 4 | import com.github.houbb.ioc.exception.IocRuntimeException; 5 | 6 | /** 7 | * 这里可以弱化 BeanFactory 的存在。 8 | * 就不再支持 BeanFactoryAware 了。 9 | *

project: ioc-BeanNameAware

10 | *

create on 2019/11/12 23:11

11 | * 12 | * @author Administrator 13 | * @since 0.0.8 14 | */ 15 | public interface ApplicationContextAware extends Aware { 16 | 17 | /** 18 | * 设置 applicationContext 的信息 19 | * @param applicationContext 上下文信息 20 | * @throws IocRuntimeException 运行时异常 21 | * @since 0.0.8 22 | */ 23 | void setApplicationContext(ApplicationContext applicationContext); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/aware/Aware.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.aware; 2 | 3 | /** 4 | * aware 信息 5 | * 6 | * 用于标识不同的生命周期,可以处理调用。 7 | * 8 | * (1)更加类似于一种通知,或者说是监听器接口。 9 | * 10 | *

project: ioc-Aware

11 | *

create on 2019/11/12 23:09

12 | * 13 | * @author Administrator 14 | * @since 0.0.8 15 | */ 16 | public interface Aware { 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/aware/BeanCreateAware.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.aware; 2 | 3 | import com.github.houbb.ioc.exception.IocRuntimeException; 4 | 5 | /** 6 | * 对象创建监听 7 | *

project: ioc-BeanNameAware

8 | *

create on 2019/11/12 23:11

9 | * 10 | * @author Administrator 11 | * @since 0.0.8 12 | */ 13 | public interface BeanCreateAware extends Aware { 14 | 15 | /** 16 | * 设值创建的对象 17 | * @param name bean 名称 18 | * @param instance 实例 19 | * @throws IocRuntimeException 运行时异常 20 | * @since 0.0.8 21 | */ 22 | void setBeanCreate(String name, final Object instance); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/aware/BeanFactoryAware.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.aware; 2 | 3 | import com.github.houbb.ioc.core.BeanFactory; 4 | 5 | /** 6 | * {@link com.github.houbb.ioc.core.BeanFactory} bean 工厂监听器 7 | * @author binbin.hou 8 | * @since 0.1.6 9 | */ 10 | public interface BeanFactoryAware extends Aware { 11 | 12 | /** 13 | * 设置 BeanFactory 14 | * @param beanFactory 对象工厂 15 | * @since 0.1.6 16 | */ 17 | void setBeanFactory(BeanFactory beanFactory); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/aware/BeanNameAware.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.aware; 2 | 3 | import com.github.houbb.ioc.exception.IocRuntimeException; 4 | 5 | /** 6 | *

project: ioc-BeanNameAware

7 | *

create on 2019/11/12 23:11

8 | * 9 | * @author Administrator 10 | * @since 0.0.8 11 | */ 12 | public interface BeanNameAware extends Aware { 13 | 14 | /** 15 | * 设置 bean 的名称 16 | * @param name bean 名称 17 | * @throws IocRuntimeException 运行时异常 18 | * @since 0.0.8 19 | */ 20 | void setBeanName(String name); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/aware/service/AwareService.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.aware.service; 2 | 3 | import com.github.houbb.ioc.context.ApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | 6 | /** 7 | * @author binbin.hou 8 | * @since 0.1.8 9 | */ 10 | public interface AwareService { 11 | 12 | /** 13 | * 设置 Bean 工厂 14 | * @param beanFactory Bean 工厂 15 | * @since 0.1.8 16 | */ 17 | void setBeanFactory(final BeanFactory beanFactory); 18 | 19 | /** 20 | * 通知所有 {@link com.github.houbb.ioc.support.aware.BeanNameAware} 对应的监听 21 | * @param beanName Bean 名称 22 | * @since 0.1.8 23 | */ 24 | void notifyAllBeanNameAware(final String beanName); 25 | 26 | /** 27 | * 通知所有上下文监听器 28 | * @param applicationContext 上下文 29 | * @since 0.1.8 30 | */ 31 | void notifyAllApplicationContextAware(final ApplicationContext applicationContext); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/aware/service/impl/DefaultAwareService.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.aware.service.impl; 2 | 3 | import com.github.houbb.ioc.context.ApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.core.ListableBeanFactory; 6 | import com.github.houbb.ioc.support.aware.ApplicationContextAware; 7 | import com.github.houbb.ioc.support.aware.BeanNameAware; 8 | import com.github.houbb.ioc.support.aware.service.AwareService; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 默认实现 14 | * @author binbin.hou 15 | * @since 0.1.8 16 | */ 17 | public class DefaultAwareService implements AwareService { 18 | 19 | /** 20 | * 对象工厂 21 | * @since 0.1.8 22 | */ 23 | private BeanFactory beanFactory; 24 | 25 | @Override 26 | public void setBeanFactory(BeanFactory beanFactory) { 27 | this.beanFactory = beanFactory; 28 | } 29 | 30 | @Override 31 | public void notifyAllBeanNameAware(String beanName) { 32 | if(this.beanFactory instanceof ListableBeanFactory) { 33 | ListableBeanFactory listableBeanFactory = (ListableBeanFactory)beanFactory; 34 | List awareList = listableBeanFactory.getBeans(BeanNameAware.class); 35 | 36 | for (BeanNameAware aware : awareList) { 37 | aware.setBeanName(beanName); 38 | } 39 | } 40 | } 41 | 42 | @Override 43 | public void notifyAllApplicationContextAware(ApplicationContext applicationContext) { 44 | if(beanFactory instanceof ListableBeanFactory) { 45 | ListableBeanFactory listableBeanFactory = (ListableBeanFactory)beanFactory; 46 | List awareList = listableBeanFactory.getBeans(ApplicationContextAware.class); 47 | 48 | for(ApplicationContextAware aware : awareList) { 49 | aware.setApplicationContext(applicationContext); 50 | } 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/condition/Condition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.condition; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * 条件接口 7 | * 注意:都应该提供无参数构造器 8 | * @author binbin.hou 9 | * @since 0.1.8 10 | */ 11 | public interface Condition { 12 | 13 | /** 14 | * 是否匹配 15 | * @param context 上下文 16 | * @param attributes 注解相关信息 17 | * @return 结果是否匹配 18 | * @since 0.1.8 19 | */ 20 | boolean matches(final ConditionContext context, final Map attributes); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/condition/ConditionContext.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.condition; 2 | 3 | import com.github.houbb.heaven.reflect.meta.annotation.IAnnotationTypeMeta; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.support.envrionment.Environment; 6 | import com.github.houbb.ioc.support.envrionment.EnvironmentCapable; 7 | import com.github.houbb.ioc.support.lifecycle.registry.BeanDefinitionRegistry; 8 | 9 | /** 10 | * 条件上下文执行接口 11 | * @author binbin.hou 12 | * @since 0.1.8 13 | */ 14 | public interface ConditionContext extends EnvironmentCapable { 15 | 16 | /** 17 | * 获取对象工厂信息 18 | * @return 工厂信息 19 | * @since 0.1.8 20 | */ 21 | BeanFactory getBeanFactory(); 22 | 23 | /** 24 | * 获取对象信息注册类 25 | * @return 对象信息注册类 26 | * @since 0.1.8 27 | */ 28 | BeanDefinitionRegistry getBeanDefinitionRegistry(); 29 | 30 | /** 31 | * 获取注解相关元信息 32 | * @return 注解元信息 33 | * @since 0.1.8 34 | */ 35 | IAnnotationTypeMeta getAnnotationTypeMeta(); 36 | 37 | } -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/condition/impl/DefaultConditionContext.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.condition.impl; 2 | 3 | import com.github.houbb.heaven.reflect.meta.annotation.IAnnotationTypeMeta; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.support.condition.ConditionContext; 6 | import com.github.houbb.ioc.support.envrionment.Environment; 7 | import com.github.houbb.ioc.support.lifecycle.registry.BeanDefinitionRegistry; 8 | 9 | /** 10 | * 条件上下文执行接口 11 | * @author binbin.hou 12 | * @since 0.1.8 13 | */ 14 | public class DefaultConditionContext implements ConditionContext { 15 | 16 | /** 17 | * 获取对象工厂信息 18 | * @since 0.1.8 19 | */ 20 | private BeanFactory beanFactory; 21 | 22 | /** 23 | * 获取对象信息注册类 24 | * @since 0.1.8 25 | */ 26 | private BeanDefinitionRegistry beanDefinitionRegistry; 27 | 28 | /** 29 | * 获取注解相关元信息 30 | * @since 0.1.8 31 | */ 32 | private IAnnotationTypeMeta annotationTypeMeta; 33 | 34 | /** 35 | * 环境信息 36 | * @since 0.1.9 37 | */ 38 | private Environment environment; 39 | 40 | @Override 41 | public BeanFactory getBeanFactory() { 42 | return beanFactory; 43 | } 44 | 45 | public void setBeanFactory(BeanFactory beanFactory) { 46 | this.beanFactory = beanFactory; 47 | } 48 | 49 | @Override 50 | public BeanDefinitionRegistry getBeanDefinitionRegistry() { 51 | return beanDefinitionRegistry; 52 | } 53 | 54 | public void setBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) { 55 | this.beanDefinitionRegistry = beanDefinitionRegistry; 56 | } 57 | 58 | @Override 59 | public IAnnotationTypeMeta getAnnotationTypeMeta() { 60 | return annotationTypeMeta; 61 | } 62 | 63 | public void setAnnotationTypeMeta(IAnnotationTypeMeta annotationTypeMeta) { 64 | this.annotationTypeMeta = annotationTypeMeta; 65 | } 66 | 67 | @Override 68 | public Environment getEnvironment() { 69 | return environment; 70 | } 71 | 72 | public void setEnvironment(Environment environment) { 73 | this.environment = environment; 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/condition/impl/ProfileCondition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.condition.impl; 2 | 3 | import com.github.houbb.ioc.support.condition.Condition; 4 | import com.github.houbb.ioc.support.condition.ConditionContext; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * 环境上下文 10 | * 11 | * (1)这里一样的只需要关心自己就行了。 12 | * (2)只要标识的环境和激活的环境有一个匹配,则认为匹配。 13 | * 14 | * @author binbin.hou 15 | * @since 0.1.9 16 | * @see com.github.houbb.ioc.annotation.Profile 环境标识 17 | */ 18 | public class ProfileCondition implements Condition { 19 | 20 | @Override 21 | public boolean matches(ConditionContext context, Map attributes) { 22 | String[] activeProfiles = context.getEnvironment().getActiveProfiles(); 23 | String[] currentProfiles = (String[]) attributes.get("value"); 24 | 25 | for(String activeProfile : activeProfiles) { 26 | for(String profile : currentProfiles) { 27 | if(activeProfile.equalsIgnoreCase(profile)) { 28 | return true; 29 | } 30 | } 31 | } 32 | 33 | return false; 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/condition/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 条件测试 3 | * @since 0.1.8 4 | */ 5 | package com.github.houbb.ioc.support.condition; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/converter/StringValueConverter.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.converter; 2 | 3 | /** 4 | * 字符串值转换类 5 | * @author binbin.hou 6 | * @since 0.0.6 7 | * @param 泛型 8 | */ 9 | public interface StringValueConverter { 10 | 11 | /** 12 | * 对字符串值进行转换 13 | * @param value 值 14 | * @return 转换后的结果 15 | */ 16 | T convert(final String value); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/converter/StringValueConverterFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.converter; 2 | 3 | import com.github.houbb.json.bs.JsonBs; 4 | 5 | /** 6 | * 字符串转换工厂类 7 | * @author binbin.hou 8 | * @since 0.0.6 9 | */ 10 | public final class StringValueConverterFactory { 11 | 12 | private StringValueConverterFactory(){} 13 | 14 | /** 15 | * 获取转换后的值 16 | * @param string 字符串 17 | * @param clazz 类型 18 | * @return 结果 19 | * @since 0.0.6 20 | */ 21 | public static Object convertValue(final String string, 22 | final Class clazz) { 23 | return JsonBs.deserialize(string, clazz); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/cycle/DependsCheckService.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.cycle; 2 | 3 | import com.github.houbb.ioc.model.BeanDefinition; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 依赖检查服务 9 | *

project: ioc-CycleService

10 | *

create on 2019/11/13 22:14

11 | * 12 | * @author Administrator 13 | * @since 0.1.0 14 | */ 15 | public interface DependsCheckService { 16 | 17 | /** 18 | * 注册所有的 bean 定义信息 19 | * @param beanDefinitionList bean 定义信息 20 | * @since 0.1.0 21 | */ 22 | void registerBeanDefinitions(final List beanDefinitionList); 23 | 24 | /** 25 | * 是否是循环依赖 26 | * @param beanName 对象名称 27 | * @return 是否依赖 28 | * @since 0.1.0 29 | */ 30 | boolean isCircleRef(String beanName); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/definition/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 对象的定义生成等操作 3 | *

project: ioc-package-info

4 | *

create on 2019/12/1 13:46

5 | * 6 | * @author Administrator 7 | * @since 0.1.11 8 | */ 9 | package com.github.houbb.ioc.support.definition; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/ConfigurableEnvironment.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | *

project: ioc-Environment

7 | *

create on 2019/11/30 14:37

8 | * 9 | * @author Administrator 10 | * @see com.github.houbb.ioc.annotation.Profile 环境标识注解 11 | * @since 0.1.9 12 | */ 13 | public interface ConfigurableEnvironment extends Environment { 14 | 15 | /** 16 | * 设置激活的环境信息 17 | * 18 | * @param activeProfiles 激活的环境信息 19 | * @since 0.1.9 20 | */ 21 | void setActiveProfiles(final String... activeProfiles); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/ConfigurablePropertyResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment; 2 | 3 | /** 4 | * 可配置的属性处理类 5 | * 6 | *

project: ioc-PropertyResolver

7 | *

create on 2019/11/30 21:30

8 | * 9 | * @author Administrator 10 | * @since 0.1.10 11 | */ 12 | public interface ConfigurablePropertyResolver extends PropertyResolver { 13 | 14 | /** 15 | * Set the prefix that placeholders replaced by this resolver must begin with. 16 | * @param placeholderPrefix 占位符开始 17 | * @since 0.1.10 18 | */ 19 | void setPlaceholderPrefix(String placeholderPrefix); 20 | 21 | /** 22 | * Set the suffix that placeholders replaced by this resolver must end with. 23 | * @param placeholderSuffix 占位符结束 24 | * @since 0.1.10 25 | */ 26 | void setPlaceholderSuffix(String placeholderSuffix); 27 | 28 | /** 29 | * Specify the separating character between the placeholders replaced by this 30 | * resolver and their associated default value, or {@code null} if no such 31 | * special character should be processed as a value separator. 32 | * 33 | * @param valueSeparator 占位符分割 34 | * @since 0.1.10 35 | */ 36 | void setValueSeparator(String valueSeparator); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/Environment.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment; 2 | 3 | /** 4 | *

project: ioc-Environment

5 | *

create on 2019/11/30 14:37

6 | * 7 | * @author Administrator 8 | * @since 0.1.9 9 | * @see com.github.houbb.ioc.annotation.Profile 环境标识注解 10 | */ 11 | public interface Environment { 12 | 13 | /** 14 | * 获取激活的环境信息 15 | * @return 环境信息 16 | * @since 0.1.9 17 | */ 18 | String[] getActiveProfiles(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/EnvironmentCapable.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment; 2 | 3 | /** 4 | *

project: ioc-Environment

5 | *

create on 2019/11/30 14:37

6 | * 7 | * @author Administrator 8 | * @since 0.1.9 9 | */ 10 | public interface EnvironmentCapable { 11 | 12 | /** 13 | * 获取环境信息依赖 14 | * @return Return the {@link Environment} associated with this component. 15 | */ 16 | Environment getEnvironment(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/PropertyResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment; 2 | 3 | /** 4 | *

project: ioc-PropertyResolver

5 | *

create on 2019/11/30 21:30

6 | * 7 | * @author Administrator 8 | * @since 0.1.10 9 | * 10 | * @see PropertySource 资源信息接口 11 | */ 12 | public interface PropertyResolver { 13 | 14 | /** 15 | * Return whether the given property key is available for resolution, i.e., 16 | * the value for the given key is not {@code null}. 17 | * @param key 键名称 18 | * @since 0.1.10 19 | * @return 是否包含指定属性 20 | */ 21 | boolean containsProperty(String key); 22 | 23 | /** 24 | * Return the property value associated with the given key, or {@code null} 25 | * if the key cannot be resolved. 26 | * @param key the property name to resolve 27 | * @return 对应的值 28 | * @since 0.1.10 29 | */ 30 | String getProperty(String key); 31 | 32 | /** 33 | * Return the property value associated with the given key, or 34 | * {@code defaultValue} if the key cannot be resolved. 35 | * @param key the property name to resolve 36 | * @param defaultValue the default value to return if no value is found 37 | * @return 对应的值 38 | * @since 0.1.10 39 | */ 40 | String getProperty(String key, String defaultValue); 41 | 42 | /** 43 | * Return the property value associated with the given key (never {@code null}). 44 | * 45 | * @param key 键 46 | * @return 结果 47 | * @since 0.1.10 48 | */ 49 | String getRequiredProperty(String key); 50 | 51 | /** 52 | * Resolve ${...} placeholders in the given text, replacing them with corresponding 53 | * property values as resolved by {@link #getProperty}. 54 | * 55 | * Unresolvable placeholders with no default value are ignored and passed through unchanged. 56 | * 57 | * @param text the String to resolve 58 | * @return the resolved String (never {@code null}) 59 | * @throws IllegalArgumentException if given text is {@code null} 60 | * @see #resolveRequiredPlaceholders 61 | */ 62 | String resolvePlaceholders(String text); 63 | 64 | /** 65 | * Resolve ${...} placeholders in the given text, replacing them with corresponding 66 | * property values as resolved by {@link #getProperty}. Unresolvable placeholders with 67 | * no default value will cause an IllegalArgumentException to be thrown. 68 | * @return the resolved String (never {@code null}) 69 | * @throws IllegalArgumentException if given text is {@code null} 70 | * or if any placeholders are unresolvable 71 | * 72 | * @param text 文本信息 73 | * @since 0.1.10 74 | */ 75 | String resolveRequiredPlaceholders(String text); 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/PropertySource.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment; 2 | 3 | /** 4 | *

project: ioc-PropertyResource

5 | *

create on 2019/11/30 21:48

6 | * 7 | * @author Administrator 8 | * @since 0.1.10 9 | */ 10 | public interface PropertySource { 11 | 12 | /** 13 | * 获取属性资源名称 14 | * @return 属性资源名称 15 | * @since 0.1.10 16 | */ 17 | String getName(); 18 | 19 | /** 20 | * Return whether this {@code PropertySource} contains the given name. 21 | *

This implementation simply checks for a {@code null} return value 22 | * from {@link #getProperty(String)}. Subclasses may wish to implement 23 | * a more efficient algorithm if possible. 24 | * @param name the property name to find 25 | * 26 | * @return 是否包含指定属性 27 | * @since 0.1.10 28 | */ 29 | boolean containsProperty(String name); 30 | 31 | /** 32 | * Return the value associated with the given name, 33 | * or {@code null} if not found. 34 | * @param name the property to find 35 | * @see PropertyResolver#getRequiredProperty(String) 36 | * 37 | * @return 对应的属性信息 38 | * @since 0.1.10 39 | */ 40 | Object getProperty(String name); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/impl/DefaultEnvironment.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment.impl; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.ioc.constant.ProfileConst; 5 | import com.github.houbb.ioc.support.envrionment.ConfigurableEnvironment; 6 | import com.github.houbb.ioc.support.envrionment.PropertySource; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | *

project: ioc-Environment

12 | *

create on 2019/11/30 14:37

13 | * 14 | * @author Administrator 15 | * @since 0.1.9 16 | * @see com.github.houbb.ioc.annotation.Profile 环境标识注解 17 | */ 18 | public class DefaultEnvironment implements ConfigurableEnvironment { 19 | 20 | /** 21 | * 被激活的信息 22 | * @since 0.1.9 23 | */ 24 | private String[] activeProfiles = new String[]{ProfileConst.DEFAULT}; 25 | 26 | /** 27 | * 资源列表 28 | * @since 0.1.10 29 | */ 30 | private List propertySources; 31 | 32 | /** 33 | * 默认实例 34 | * @return 默认实例 35 | * @since 0.1.9 36 | */ 37 | public static ConfigurableEnvironment defaultInstance() { 38 | return new DefaultEnvironment(); 39 | } 40 | 41 | @Override 42 | public void setActiveProfiles(String... activeProfiles) { 43 | ArgUtil.notEmpty(activeProfiles, "activeProfiles"); 44 | 45 | this.activeProfiles = activeProfiles; 46 | } 47 | 48 | @Override 49 | public String[] getActiveProfiles() { 50 | return activeProfiles; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/impl/MapPropertySource.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment.impl; 2 | 3 | import com.github.houbb.ioc.support.envrionment.PropertySource; 4 | 5 | import java.util.Map; 6 | 7 | /** 8 | *

project: ioc-MapPropertySource

9 | *

create on 2019/11/30 21:55

10 | * 11 | * @author Administrator 12 | * @since 0.1.10 13 | */ 14 | public class MapPropertySource implements PropertySource> { 15 | 16 | /** 17 | * 资源名称 18 | * @since 0.1.10 19 | */ 20 | private String name; 21 | 22 | /** 23 | * 资源信息 24 | * @since 0.1.10 25 | */ 26 | private Map source; 27 | 28 | public MapPropertySource(String name, Map source) { 29 | this.name = name; 30 | this.source = source; 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return this.name; 36 | } 37 | 38 | @Override 39 | public boolean containsProperty(String name) { 40 | return source.containsKey(name); 41 | } 42 | 43 | @Override 44 | public Object getProperty(String name) { 45 | return source.get(name); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/impl/PropertiesPropertySource.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment.impl; 2 | 3 | import java.util.Map; 4 | import java.util.Properties; 5 | 6 | /** 7 | *

project: ioc-MapPropertySource

8 | *

create on 2019/11/30 21:55

9 | * 10 | * @author Administrator 11 | * @since 0.1.10 12 | */ 13 | public class PropertiesPropertySource extends MapPropertySource { 14 | 15 | @SuppressWarnings("unchecked") 16 | public PropertiesPropertySource(String name, Properties source) { 17 | super(name, (Map) source); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/envrionment/impl/PropertySourcesPropertyResolver.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.envrionment.impl; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.guava.Guavas; 5 | import com.github.houbb.heaven.util.lang.ObjectUtil; 6 | import com.github.houbb.ioc.exception.IocRuntimeException; 7 | import com.github.houbb.ioc.support.envrionment.ConfigurablePropertyResolver; 8 | import com.github.houbb.ioc.support.envrionment.PropertySource; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | *

project: ioc-PropertySourcePropertyResolver

14 | *

create on 2019/11/30 21:45

15 | * 16 | * @author Administrator 17 | * @see PropertySource 配置资源信息 18 | * @since 0.1.10 19 | */ 20 | public class PropertySourcesPropertyResolver implements ConfigurablePropertyResolver { 21 | 22 | /** 23 | * 前缀 24 | * @since 0.1.10 25 | */ 26 | private String placeholderPrefix = "${"; 27 | 28 | /** 29 | * 后缀 30 | * @since 0.1.10 31 | */ 32 | private String placeholderSuffix = "}"; 33 | 34 | /** 35 | * 分隔符 36 | * @since 0.1.10 37 | */ 38 | private String valueSeparator = ":"; 39 | 40 | /** 41 | * 可遍历的资源信息 42 | * @since 0.1.10 43 | */ 44 | private List propertySourceList = Guavas.newArrayList(); 45 | 46 | public PropertySourcesPropertyResolver(List propertySourceList) { 47 | ArgUtil.notNull(propertySourceList, "propertySourceList"); 48 | 49 | this.propertySourceList = propertySourceList; 50 | } 51 | 52 | @Override 53 | public void setPlaceholderPrefix(String placeholderPrefix) { 54 | this.placeholderPrefix = placeholderPrefix; 55 | } 56 | 57 | @Override 58 | public void setPlaceholderSuffix(String placeholderSuffix) { 59 | this.placeholderSuffix = placeholderSuffix; 60 | } 61 | 62 | @Override 63 | public void setValueSeparator(String valueSeparator) { 64 | this.valueSeparator = valueSeparator; 65 | } 66 | 67 | @Override 68 | public boolean containsProperty(String key) { 69 | for(PropertySource propertySource : propertySourceList) { 70 | if(propertySource.containsProperty(key)) { 71 | return true; 72 | } 73 | } 74 | return false; 75 | } 76 | 77 | @Override 78 | public String getProperty(String key) { 79 | return getProperty(key, null); 80 | } 81 | 82 | @Override 83 | public String getProperty(String key, String defaultValue) { 84 | for(PropertySource propertySource : propertySourceList) { 85 | if(propertySource.containsProperty(key)) { 86 | return (String) propertySource.getProperty(key); 87 | } 88 | } 89 | return defaultValue; 90 | } 91 | 92 | @Override 93 | public String getRequiredProperty(String key) { 94 | String value = getProperty(key); 95 | if(ObjectUtil.isNull(value)) { 96 | throw new IocRuntimeException("Can't resolve property for key " + key); 97 | } 98 | return value; 99 | } 100 | 101 | @Override 102 | public String resolvePlaceholders(String text) { 103 | ArgUtil.notEmpty(text, "text"); 104 | 105 | return resolvePlaceholder(text, false); 106 | } 107 | 108 | @Override 109 | public String resolveRequiredPlaceholders(String text) { 110 | ArgUtil.notEmpty(text, "text"); 111 | 112 | return resolvePlaceholder(text, true); 113 | } 114 | 115 | private String resolvePlaceholder(final String text, final boolean required) { 116 | if(text.startsWith(placeholderPrefix) && text.endsWith(placeholderSuffix)) { 117 | String placeholder = text.substring(2, text.length()-1); 118 | 119 | String[] strings = placeholder.split(valueSeparator); 120 | String key = strings[0]; 121 | 122 | if(strings.length == 1) { 123 | // 断言必须存在 124 | return getRequiredProperty(key); 125 | } 126 | 127 | // 第一个为键,第二个为默认值 128 | String defaultValue = strings[1]; 129 | return getProperty(key, defaultValue); 130 | } 131 | 132 | return text; 133 | } 134 | 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/DisposableBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle; 2 | 3 | /** 4 | * 对象被销毁之前调用 5 | * 6 | * Destroy methods are called in the same order: 7 | * 8 | * 1. Methods annotated with @PreDestroy 9 | * 10 | * 2. destroy() as defined by the DisposableBean callback interface 11 | * 12 | * 3. A custom configured destroy() method 13 | * 14 | *

project: ioc-DisposableBean

15 | *

create on 2019/11/8 20:55

16 | * 17 | * @author Administrator 18 | * @since 0.0.4 19 | */ 20 | public interface DisposableBean { 21 | 22 | /** 23 | * 销毁方法 24 | * @since 0.0.4 25 | */ 26 | void destroy(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/InitializingBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle; 2 | 3 | /** 4 | * Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows: 5 | * 6 | * 1. Methods annotated with @PostConstruct 7 | * 8 | * 2. initialize() as defined by the InitializingBean callback interface 9 | * 10 | * 3. A custom configured init() method 11 | * 12 | *

project: ioc-InitializingBean

13 | *

create on 2019/11/8 20:53

14 | * 15 | * @author Administrator 16 | * @since 0.0.4 17 | */ 18 | public interface InitializingBean { 19 | 20 | /** 21 | * 对象初始化完成之后调用 22 | * @since 0.0.4 23 | */ 24 | void initialize(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/NewInstanceBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle; 2 | 3 | import com.github.houbb.heaven.util.lang.ObjectUtil; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.model.BeanDefinition; 6 | 7 | /** 8 | * 创建一个对象,有四种方式,你会吗? 9 | * 10 | * (1)直接使用 {@link BeanDefinition#getFactoryMethod()} 创建对象 11 | * (2)根据构造器创建对象 12 | * 2.1 默认无参构造器 13 | * 2.2 通过指定的构造器信息创建 14 | * 15 | *

project: ioc-InitializingBean

16 | *

create on 2019/11/8 20:53

17 | * 18 | * @author Administrator 19 | * @since 0.0.6 20 | */ 21 | public interface NewInstanceBean { 22 | 23 | /** 24 | * 对象初始化完成之后调用 25 | * @param beanFactory 属性工厂 26 | * @param beanDefinition 对象基本信息定义 27 | * @return 对象实例 28 | * @since 0.0.6 29 | */ 30 | Object newInstance(final BeanFactory beanFactory, final BeanDefinition beanDefinition); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/create/AbstractNewInstanceBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.create; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.util.common.ArgUtil; 5 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 6 | import com.github.houbb.heaven.util.util.Optional; 7 | import com.github.houbb.ioc.core.BeanFactory; 8 | import com.github.houbb.ioc.model.BeanDefinition; 9 | import com.github.houbb.ioc.support.lifecycle.NewInstanceBean; 10 | 11 | /** 12 | * 抽象对象实例的实现 13 | * @author binbin.hou 14 | * @since 0.0.6 15 | */ 16 | @ThreadSafe 17 | abstract class AbstractNewInstanceBean implements NewInstanceBean { 18 | 19 | /** 20 | * 创建新对象实例 21 | * @param beanFactory 对象工厂 22 | * @param beanClass 类信息 23 | * @param beanDefinition 对象定义信息 24 | * @return 实例 optional 信息 25 | * @since 0.0.6 26 | */ 27 | protected abstract Optional newInstanceOpt(final BeanFactory beanFactory, 28 | final BeanDefinition beanDefinition, 29 | final Class beanClass); 30 | 31 | @Override 32 | public Object newInstance(final BeanFactory beanFactory, BeanDefinition beanDefinition) { 33 | ArgUtil.notNull(beanFactory, "beanFactory"); 34 | ArgUtil.notNull(beanDefinition, "beanDefinition"); 35 | 36 | final Class beanClass = ClassUtil.getClass(beanDefinition.getClassName()); 37 | Optional optional = newInstanceOpt(beanFactory, beanDefinition, beanClass); 38 | return optional.orElseNull(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/create/ConstructorNewInstanceBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.create; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.support.tuple.impl.Pair; 5 | import com.github.houbb.heaven.util.lang.StringUtil; 6 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 7 | import com.github.houbb.heaven.util.lang.reflect.ReflectConstructorUtil; 8 | import com.github.houbb.heaven.util.util.CollectionUtil; 9 | import com.github.houbb.heaven.util.util.Optional; 10 | import com.github.houbb.ioc.core.BeanFactory; 11 | import com.github.houbb.ioc.model.BeanDefinition; 12 | import com.github.houbb.ioc.model.ConstructorArgDefinition; 13 | import com.github.houbb.ioc.support.converter.StringValueConverterFactory; 14 | 15 | import java.lang.reflect.Constructor; 16 | import java.util.List; 17 | 18 | /** 19 | * 根据构造器创建对象 20 | * @author binbin.hou 21 | * @since 0.0.6 22 | */ 23 | @ThreadSafe 24 | class ConstructorNewInstanceBean extends AbstractNewInstanceBean { 25 | 26 | private static final ConstructorNewInstanceBean INSTANCE = new ConstructorNewInstanceBean(); 27 | 28 | /** 29 | * 获取单例实例 30 | * @return 单例 31 | * @since 0.0.6 32 | */ 33 | public static ConstructorNewInstanceBean getInstance() { 34 | return INSTANCE; 35 | } 36 | 37 | /** 38 | * 1. 获取所有的构造器列表 {@link Class#getConstructors()} 39 | * 2. 通过 {@link BeanDefinition} 指定的信息列表处理,选择精确匹配的构造器 40 | * 3. 反射调用构造器创建对象实例。{@link java.lang.reflect.Constructor#newInstance(Object...)} 41 | * 3.1 反射的时候注意构造器的访问级别。 42 | * 43 | * 这里有一个问题: 44 | * (1)我们每次处理 class 都需要重复处理 class 的反射信息,如何才能统一获取这些类的元信息, 45 | * 提供属性工具类? 46 | * (2)或者每次启动前,类似 spring,统一将所有的 class 元数据信息整理好。 47 | * 48 | * 如果这是一个普通系统,选择(1)比较好,延迟加载。 49 | * 如果这是一个实时系统,建议使用(2),初期启动比较慢,启动完成之后则比较快。 50 | * 51 | * @param beanFactory 对象工厂 52 | * @param beanDefinition 对象定义信息 53 | * @param beanClass 类信息 54 | * @return 结果 55 | * @since 0.0.6 56 | */ 57 | @Override 58 | protected Optional newInstanceOpt(BeanFactory beanFactory, BeanDefinition beanDefinition, Class beanClass) { 59 | final List argDefinitionList = beanDefinition.getConstructorArgList(); 60 | 61 | //1. 无参构造器 62 | if(CollectionUtil.isEmpty(argDefinitionList)) { 63 | return newInstanceOpt(beanClass); 64 | } 65 | 66 | //2. 根据指定参数信息获取对应构造器 67 | return newInstanceOpt(beanFactory, beanClass, argDefinitionList); 68 | } 69 | 70 | /** 71 | * 直接获取实例对象 72 | * @param beanClass 类信息 73 | * @return 实例结果 74 | * @since 0.0.6 75 | */ 76 | private Optional newInstanceOpt(final Class beanClass) { 77 | Object instance = ClassUtil.newInstance(beanClass); 78 | return Optional.of(instance); 79 | } 80 | 81 | /** 82 | * 直接获取实例对象 83 | * @param beanFactory bean 工厂 84 | * @param beanClass 类信息 85 | * @param argDefinitionList 参数定义列表信息 86 | * @return 实例结果 87 | * @since 0.0.6 88 | */ 89 | private Optional newInstanceOpt(final BeanFactory beanFactory, 90 | final Class beanClass, 91 | final List argDefinitionList) { 92 | Pair pair = getParamsPair(beanFactory, argDefinitionList); 93 | Constructor constructor = ClassUtil.getConstructor(beanClass, pair.getValueOne()); 94 | Object instance = ReflectConstructorUtil.newInstance(constructor, pair.getValueTwo()); 95 | return Optional.of(instance); 96 | } 97 | 98 | /** 99 | * 构建参数信息 100 | * 101 | * TODO: 引用类可能存在循环引用问题。如何判断是否存在循环依赖? 102 | * 103 | * 这是个图问题? 104 | * 105 | * 参考资料: 106 | * [Spring循环依赖检查算法分析](https://www.iteye.com/blog/jingzhongwen-2208921) 107 | * 108 | * http://ifeve.com/%E8%AE%BAspring%E4%B8%AD%E5%BE%AA%E7%8E%AF%E4%BE%9D%E8%B5%96%E7%9A%84%E6%AD%A3%E7%A1%AE%E6%80%A7%E4%B8%8Ebean%E6%B3%A8%E5%85%A5%E7%9A%84%E9%A1%BA%E5%BA%8F%E5%85%B3%E7%B3%BB/ 109 | * @param beanFactory bean 工厂信息 110 | * @param argDefinitionList 参数列表 111 | * @return pair 信息 112 | * @since 0.0.6 113 | */ 114 | private Pair getParamsPair(final BeanFactory beanFactory, 115 | final List argDefinitionList) { 116 | final int size = argDefinitionList.size(); 117 | Class[] types = new Class[size]; 118 | Object[] values = new Object[size]; 119 | 120 | for(int i = 0; i < size; i++) { 121 | ConstructorArgDefinition argDefinition = argDefinitionList.get(i); 122 | final String ref = argDefinition.getRef(); 123 | // 引用类型 124 | if(StringUtil.isNotEmpty(ref)) { 125 | // 这里可以对常见的几个类型进行处理简化输入,后期考虑改。 126 | Class refType = beanFactory.getType(ref); 127 | Object refValue = beanFactory.getBean(ref); 128 | 129 | types[i] = refType; 130 | values[i] = refValue; 131 | } else { 132 | // 指定值类型 133 | Class valueType = ClassUtil.getClass(argDefinition.getType()); 134 | final String valueStr = argDefinition.getValue(); 135 | Object value = StringValueConverterFactory.convertValue(valueStr, valueType); 136 | 137 | types[i] = valueType; 138 | values[i] = value; 139 | } 140 | } 141 | 142 | return Pair.of(types, values); 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/create/DefaultNewInstanceBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.create; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.util.lang.ObjectUtil; 5 | import com.github.houbb.ioc.constant.enums.BeanSourceTypeEnum; 6 | import com.github.houbb.ioc.core.BeanFactory; 7 | import com.github.houbb.ioc.core.ListableBeanFactory; 8 | import com.github.houbb.ioc.model.BeanDefinition; 9 | import com.github.houbb.ioc.support.lifecycle.NewInstanceBean; 10 | import com.github.houbb.ioc.support.lifecycle.property.impl.DefaultBeanPropertyProcessor; 11 | import com.github.houbb.ioc.support.processor.BeanPostProcessor; 12 | import com.github.houbb.ioc.support.processor.impl.AutowiredAnnotationBeanPostProcessor; 13 | 14 | import java.util.List; 15 | 16 | /** 17 | * 默认新建对象实例的实现 18 | * @author binbin.hou 19 | * @since 0.0.6 20 | */ 21 | @ThreadSafe 22 | public class DefaultNewInstanceBean implements NewInstanceBean { 23 | 24 | /** 25 | * 单例 26 | * @since 0.0.6 27 | */ 28 | private static final DefaultNewInstanceBean INSTANCE = new DefaultNewInstanceBean(); 29 | 30 | /** 31 | * 获取实例 32 | * @return 实例 33 | * @since 0.0.6 34 | */ 35 | public static DefaultNewInstanceBean getInstance() { 36 | return INSTANCE; 37 | } 38 | 39 | @Override 40 | public Object newInstance(BeanFactory beanFactory, BeanDefinition beanDefinition) { 41 | Object instance; 42 | final BeanSourceTypeEnum sourceType = beanDefinition.getBeanSourceType(); 43 | 44 | //1. 工厂方法创建 45 | Object factoryMethodBean = FactoryMethodNewInstanceBean.getInstance() 46 | .newInstance(beanFactory, beanDefinition); 47 | if(ObjectUtil.isNotNull(factoryMethodBean)) { 48 | instance = factoryMethodBean; 49 | } else if(BeanSourceTypeEnum.CONFIGURATION_BEAN.equals(sourceType)) { 50 | //config-bean 51 | instance = ConfigurationMethodBean.getInstance().newInstance(beanFactory, beanDefinition); 52 | } else { 53 | //3 根据构造器创建 54 | instance = ConstructorNewInstanceBean.getInstance() 55 | .newInstance(beanFactory, beanDefinition); 56 | } 57 | 58 | //2.1 通知 BeanPostProcessor 59 | final String beanName = beanDefinition.getName(); 60 | List beanPostProcessorList = getBeanPostProcessorList(beanFactory); 61 | for(BeanPostProcessor processor : beanPostProcessorList) { 62 | instance = processor.beforePropertySet(beanName, instance); 63 | } 64 | 65 | //3. 属性设置 66 | DefaultBeanPropertyProcessor.getInstance() 67 | .propertyProcessor(beanFactory, instance, beanDefinition.getPropertyArgList()); 68 | for(BeanPostProcessor processor : beanPostProcessorList) { 69 | instance = processor.afterPropertySet(beanName, instance); 70 | } 71 | 72 | //4. 返回结果 73 | return instance; 74 | } 75 | 76 | /** 77 | * 获取 {@link BeanPostProcessor} 对应的列表信息 78 | * @param beanFactory 对象工厂 79 | * @return 对象列表 80 | * @since 0.1.6 81 | */ 82 | private List getBeanPostProcessorList(final BeanFactory beanFactory) { 83 | ListableBeanFactory listableBeanFactory = (ListableBeanFactory)beanFactory; 84 | List beanPostProcessorList = listableBeanFactory.getBeans(BeanPostProcessor.class); 85 | 86 | AutowiredAnnotationBeanPostProcessor beanPostProcessor = new AutowiredAnnotationBeanPostProcessor(); 87 | beanPostProcessor.setBeanFactory(listableBeanFactory); 88 | beanPostProcessorList.add(beanPostProcessor); 89 | return beanPostProcessorList; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/create/FactoryMethodNewInstanceBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.create; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.util.lang.StringUtil; 5 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 6 | import com.github.houbb.heaven.util.lang.reflect.ReflectMethodUtil; 7 | import com.github.houbb.heaven.util.util.Optional; 8 | import com.github.houbb.ioc.annotation.FactoryMethod; 9 | import com.github.houbb.ioc.core.BeanFactory; 10 | import com.github.houbb.ioc.model.BeanDefinition; 11 | 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * 根据静态方法创建对象实例 16 | * @author binbin.hou 17 | * @since 0.0.6 18 | */ 19 | @ThreadSafe 20 | class FactoryMethodNewInstanceBean extends AbstractNewInstanceBean { 21 | 22 | /** 23 | * 创建对象实例 24 | * @since 0.0.6 25 | */ 26 | private static final FactoryMethodNewInstanceBean INSTANCE = new FactoryMethodNewInstanceBean(); 27 | 28 | /** 29 | * 获取对象实例 30 | * @since 0.0.6 31 | */ 32 | static FactoryMethodNewInstanceBean getInstance() { 33 | return INSTANCE; 34 | } 35 | 36 | 37 | @Override 38 | protected Optional newInstanceOpt(BeanFactory beanFactory, BeanDefinition beanDefinition, Class beanClass) { 39 | //1. 指定了该方法 40 | Optional customOpt = newInstance(beanClass, beanDefinition.getFactoryMethod()); 41 | if(customOpt.isPresent()) { 42 | return customOpt; 43 | } 44 | 45 | //2. 通过注解指定 46 | return newInstance(beanClass); 47 | } 48 | 49 | /** 50 | * 根据指定的方法名称创建对象信息 51 | * @param beanClass 对象信息 52 | * @param factoryMethodName 方法名称 53 | * @return 实例结果 54 | * @since 0.0.6 55 | */ 56 | private Optional newInstance(final Class beanClass, 57 | final String factoryMethodName) { 58 | if(StringUtil.isNotEmpty(factoryMethodName)) { 59 | final Method factoryMethod = ClassUtil.getMethod(beanClass, factoryMethodName); 60 | Object result = ReflectMethodUtil.invokeFactoryMethod(beanClass, factoryMethod); 61 | return Optional.of(result); 62 | } 63 | 64 | return Optional.empty(); 65 | } 66 | 67 | /** 68 | * 根据注解获取对应的信息 69 | * @param beanClass bean class 信息 70 | * @return 实例 71 | * @since 0.0.6 72 | */ 73 | private Optional newInstance(final Class beanClass) { 74 | Optional methodOptional = ReflectMethodUtil.getMethodOptional(beanClass, FactoryMethod.class); 75 | 76 | if(methodOptional.isNotPresent()) { 77 | return Optional.empty(); 78 | } 79 | 80 | Method factoryMethod = methodOptional.get(); 81 | Object result = ReflectMethodUtil.invokeFactoryMethod(beanClass, factoryMethod); 82 | return Optional.of(result); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/destroy/DefaultPreDestroyBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.destroy; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.lang.StringUtil; 5 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 6 | import com.github.houbb.heaven.util.lang.reflect.ReflectMethodUtil; 7 | import com.github.houbb.heaven.util.util.Optional; 8 | import com.github.houbb.ioc.model.BeanDefinition; 9 | import com.github.houbb.ioc.support.lifecycle.DisposableBean; 10 | 11 | import javax.annotation.PreDestroy; 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * 默认创建对象初始化 16 | *

project: ioc-DefaultCreateBeanInit

17 | *

create on 2019/11/8 21:37

18 | * 19 | * 1. Methods annotated with {@link javax.annotation.PreDestroy} 20 | * 2. destroy() as defined by the {@link com.github.houbb.ioc.support.lifecycle.DisposableBean} callback interface 21 | * 3. A custom configured destroy() method 22 | * 23 | * 针对注解(1)的处理,需要 class 信息结合 {@link BeanDefinition} 进行注解相关信息的拓展。 24 | * 25 | * 26 | * [spring注解之@PreDestroy的实现原理](https://www.jianshu.com/p/70d18e65a1d5) 27 | * 28 | * @author Administrator 29 | * @since 0.0.4 30 | */ 31 | public class DefaultPreDestroyBean implements DisposableBean { 32 | 33 | /** 34 | * 对象实例 35 | * @since 0.0.4 36 | */ 37 | private final Object instance; 38 | 39 | /** 40 | * 对象属性定义 41 | * @since 0.0.4 42 | */ 43 | private final BeanDefinition beanDefinition; 44 | 45 | /** 46 | * 实例类型信息 47 | * @since 0.0.5 48 | */ 49 | private final Class instanceClass; 50 | 51 | public DefaultPreDestroyBean(Object instance, BeanDefinition beanDefinition) { 52 | ArgUtil.notNull(instance, "instance"); 53 | ArgUtil.notNull(beanDefinition, "beanDefinition"); 54 | 55 | this.instance = instance; 56 | this.beanDefinition = beanDefinition; 57 | this.instanceClass = instance.getClass(); 58 | } 59 | 60 | @Override 61 | public void destroy() { 62 | preDestroy(); 63 | 64 | disposableBean(); 65 | 66 | customDestroy(); 67 | } 68 | 69 | /** 70 | * 注解处理 71 | * @since 0.0.4 72 | */ 73 | private void preDestroy() { 74 | Optional methodOptional = ReflectMethodUtil.getMethodOptional(instanceClass, PreDestroy.class); 75 | if(methodOptional.isNotPresent()) { 76 | return; 77 | } 78 | 79 | //执行执行调用 80 | ReflectMethodUtil.invokeNoArgsMethod(instance, methodOptional.get()); 81 | } 82 | 83 | /** 84 | * 接口处理 85 | * @since 0.0.4 86 | */ 87 | private void disposableBean() { 88 | if(instance instanceof DisposableBean) { 89 | DisposableBean disposableBean = (DisposableBean)instance; 90 | disposableBean.destroy(); 91 | } 92 | } 93 | 94 | /** 95 | * 自定义初始化函数 96 | * @since 0.0.4 97 | */ 98 | private void customDestroy() { 99 | String destroyName = beanDefinition.getDestroy(); 100 | if(StringUtil.isEmpty(destroyName)) { 101 | return; 102 | } 103 | 104 | final Method method = ClassUtil.getMethod(instanceClass, destroyName); 105 | ReflectMethodUtil.invoke(instance, method); 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/init/DefaultPostConstructBean.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.init; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.lang.StringUtil; 5 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 6 | import com.github.houbb.heaven.util.lang.reflect.ReflectMethodUtil; 7 | import com.github.houbb.heaven.util.util.Optional; 8 | import com.github.houbb.ioc.model.BeanDefinition; 9 | import com.github.houbb.ioc.support.lifecycle.InitializingBean; 10 | 11 | import javax.annotation.PostConstruct; 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * 默认创建对象初始化 16 | *

project: ioc-DefaultCreateBeanInit

17 | *

create on 2019/11/8 21:37

18 | * 19 | * (1)注解 {@link javax.annotation.PostConstruct} 20 | * (2)添加 {@link com.github.houbb.ioc.support.lifecycle.InitializingBean} 初始化相关处理 21 | * (3)添加 {@link BeanDefinition#getInitialize()} 初始化相关处理 22 | * 23 | * 针对注解(1)的处理,需要 class 信息结合 {@link BeanDefinition} 进行注解相关信息的拓展。 24 | * 25 | * @author Administrator 26 | * @since 0.0.4 27 | */ 28 | public class DefaultPostConstructBean implements InitializingBean { 29 | 30 | /** 31 | * 对象实例 32 | * @since 0.0.4 33 | */ 34 | private final Object instance; 35 | 36 | /** 37 | * 对象实例类型 38 | * @since 0.0.5 39 | */ 40 | private final Class instanceClass; 41 | 42 | /** 43 | * 对象属性定义 44 | * @since 0.0.4 45 | */ 46 | private final BeanDefinition beanDefinition; 47 | 48 | public DefaultPostConstructBean(Object instance, BeanDefinition beanDefinition) { 49 | ArgUtil.notNull(instance, "instance"); 50 | ArgUtil.notNull(beanDefinition, "beanDefinition"); 51 | 52 | this.instance = instance; 53 | this.beanDefinition = beanDefinition; 54 | this.instanceClass = instance.getClass(); 55 | } 56 | 57 | @Override 58 | public void initialize() { 59 | 60 | postConstruct(); 61 | 62 | initializingBean(); 63 | 64 | customInit(); 65 | } 66 | 67 | /** 68 | * 注解处理 69 | * @since 0.0.4 70 | */ 71 | private void postConstruct() { 72 | Optional methodOptional = ReflectMethodUtil.getMethodOptional(instanceClass, PostConstruct.class); 73 | if(methodOptional.isNotPresent()) { 74 | return; 75 | } 76 | 77 | // 执行调用 78 | ReflectMethodUtil.invokeNoArgsMethod(instance, methodOptional.get()); 79 | } 80 | 81 | /** 82 | * 接口处理 83 | * @since 0.0.4 84 | */ 85 | private void initializingBean() { 86 | if(instance instanceof InitializingBean) { 87 | InitializingBean initializingBean = (InitializingBean)instance; 88 | initializingBean.initialize(); 89 | } 90 | } 91 | 92 | /** 93 | * 自定义初始化函数 94 | * @since 0.0.4 95 | */ 96 | private void customInit() { 97 | String initName = beanDefinition.getInitialize(); 98 | if(StringUtil.isEmpty(initName)) { 99 | return; 100 | } 101 | 102 | final Method method = ClassUtil.getMethod(instanceClass, initName); 103 | ReflectMethodUtil.invokeNoArgsMethod(instance, method); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 生命周期相关 3 | *

project: ioc-package-info

4 | *

create on 2019/11/8 20:52

5 | * 6 | * (1) 创建之后 7 | * (2) 销毁之前 8 | * (3) 其他各种阶段的 Aware 9 | * @author Administrator 10 | * @since 0.0.4 11 | */ 12 | package com.github.houbb.ioc.support.lifecycle; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/property/BeanPropertyProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.property; 2 | 3 | import com.github.houbb.ioc.core.BeanFactory; 4 | import com.github.houbb.ioc.model.BeanDefinition; 5 | import com.github.houbb.ioc.model.PropertyArgDefinition; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * 对象属性设置类。 11 | * 12 | * 主要分为两个部分: 13 | * 14 | * (1)直接根据属性值设置 15 | * (2)根据引用属性设置 16 | * 17 | *

project: ioc-BeanPropertyProcessor

18 | *

create on 2019/11/8 20:53

19 | * 20 | * @author houbinbin 21 | * @since 0.0.7 22 | */ 23 | public interface BeanPropertyProcessor { 24 | 25 | /** 26 | * 对象初始化完成之后调用 27 | * @param beanFactory 属性工厂 28 | * @param instance 对象实例 29 | * @param propertyArgList 参数信息列表 30 | * @since 0.0.7 31 | */ 32 | void propertyProcessor(final BeanFactory beanFactory, 33 | final Object instance, 34 | final List propertyArgList); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/property/SingleBeanPropertyProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.property; 2 | 3 | import com.github.houbb.ioc.core.BeanFactory; 4 | import com.github.houbb.ioc.model.PropertyArgDefinition; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 单个对象属性设置类。 10 | * 11 | * 主要分为两个部分: 12 | * 13 | * (1)直接根据属性值设置 14 | * (2)根据引用属性设置 15 | * 16 | *

project: ioc-BeanPropertyProcessor

17 | *

create on 2019/11/8 20:53

18 | * 19 | * @author houbinbin 20 | * @since 0.0.7 21 | */ 22 | public interface SingleBeanPropertyProcessor { 23 | 24 | /** 25 | * 对象初始化完成之后调用 26 | * @param beanFactory 属性工厂 27 | * @param instance 对象实例 28 | * @param propertyArgDefinition 参数信息 29 | * @since 0.0.7 30 | */ 31 | void propertyProcessor(final BeanFactory beanFactory, 32 | final Object instance, 33 | PropertyArgDefinition propertyArgDefinition); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/property/impl/DefaultBeanPropertyProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.property.impl; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.util.lang.ObjectUtil; 5 | import com.github.houbb.heaven.util.lang.StringUtil; 6 | import com.github.houbb.heaven.util.util.CollectionUtil; 7 | import com.github.houbb.ioc.core.BeanFactory; 8 | import com.github.houbb.ioc.model.PropertyArgDefinition; 9 | import com.github.houbb.ioc.support.lifecycle.property.BeanPropertyProcessor; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * 对象属性设置类。 15 | * 16 | * 主要分为两个部分: 17 | * 18 | * (1)直接根据属性值设置 19 | * (2)根据引用属性设置 20 | * 21 | *

project: ioc-BeanPropertyProcessor

22 | *

create on 2019/11/8 20:53

23 | * 24 | * @author houbinbin 25 | * @since 0.0.7 26 | */ 27 | @ThreadSafe 28 | public class DefaultBeanPropertyProcessor implements BeanPropertyProcessor { 29 | 30 | private static final DefaultBeanPropertyProcessor INSTANCE = new DefaultBeanPropertyProcessor(); 31 | 32 | public static DefaultBeanPropertyProcessor getInstance() { 33 | return INSTANCE; 34 | } 35 | 36 | @Override 37 | public void propertyProcessor(BeanFactory beanFactory, Object instance, List propertyArgList) { 38 | if(CollectionUtil.isEmpty(propertyArgList) 39 | || ObjectUtil.isNull(instance)) { 40 | return; 41 | } 42 | 43 | for(PropertyArgDefinition argDefinition : propertyArgList) { 44 | if(ObjectUtil.isNull(argDefinition)) { 45 | continue; 46 | } 47 | 48 | final String ref = argDefinition.getRef(); 49 | if(StringUtil.isEmpty(ref)) { 50 | ValueBeanPropertyProcessor.getInstance() 51 | .propertyProcessor(beanFactory, instance, argDefinition); 52 | } else { 53 | RefBeanPropertyProcessor.getInstance() 54 | .propertyProcessor(beanFactory, instance, argDefinition); 55 | } 56 | } 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/property/impl/RefBeanPropertyProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.property.impl; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.util.lang.reflect.ReflectMethodUtil; 5 | import com.github.houbb.ioc.core.BeanFactory; 6 | import com.github.houbb.ioc.model.PropertyArgDefinition; 7 | import com.github.houbb.ioc.support.lifecycle.property.SingleBeanPropertyProcessor; 8 | 9 | /** 10 | * 对象属性设置类。 11 | * 12 | * 主要分为两个部分: 13 | * 14 | * (1)直接根据属性值设置 15 | * (2)根据引用属性设置 16 | * 17 | *

project: ioc-BeanPropertyProcessor

18 | *

create on 2019/11/8 20:53

19 | * 20 | * @author houbinbin 21 | * @since 0.0.7 22 | */ 23 | @ThreadSafe 24 | class RefBeanPropertyProcessor implements SingleBeanPropertyProcessor { 25 | 26 | private static final RefBeanPropertyProcessor INSTANCE = new RefBeanPropertyProcessor(); 27 | 28 | public static RefBeanPropertyProcessor getInstance() { 29 | return INSTANCE; 30 | } 31 | 32 | @Override 33 | public void propertyProcessor(BeanFactory beanFactory, Object instance, 34 | PropertyArgDefinition propertyArgDefinition) { 35 | final String refStr = propertyArgDefinition.getRef(); 36 | 37 | Object ref = beanFactory.getBean(refStr); 38 | ReflectMethodUtil.invokeSetterMethod(instance, propertyArgDefinition.getName(), ref); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/property/impl/ValueBeanPropertyProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.property.impl; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 5 | import com.github.houbb.heaven.util.lang.reflect.ReflectFieldUtil; 6 | import com.github.houbb.heaven.util.lang.reflect.ReflectMethodUtil; 7 | import com.github.houbb.ioc.core.BeanFactory; 8 | import com.github.houbb.ioc.model.PropertyArgDefinition; 9 | import com.github.houbb.ioc.support.converter.StringValueConverterFactory; 10 | import com.github.houbb.ioc.support.lifecycle.property.SingleBeanPropertyProcessor; 11 | 12 | import java.lang.reflect.Field; 13 | 14 | /** 15 | * 对象属性设置类。 16 | * 17 | * 主要分为两个部分: 18 | * 19 | * (1)直接根据属性值设置 20 | * (2)根据引用属性设置 21 | * 22 | *

project: ioc-BeanPropertyProcessor

23 | *

create on 2019/11/8 20:53

24 | * 25 | * @author houbinbin 26 | * @since 0.0.7 27 | */ 28 | @ThreadSafe 29 | class ValueBeanPropertyProcessor implements SingleBeanPropertyProcessor { 30 | 31 | private static final ValueBeanPropertyProcessor INSTANCE = new ValueBeanPropertyProcessor(); 32 | 33 | public static ValueBeanPropertyProcessor getInstance() { 34 | return INSTANCE; 35 | } 36 | 37 | @Override 38 | public void propertyProcessor(BeanFactory beanFactory, Object instance, PropertyArgDefinition propertyArgDefinition) { 39 | String valueStr = propertyArgDefinition.getValue(); 40 | String typeStr = propertyArgDefinition.getType(); 41 | boolean fieldBase = propertyArgDefinition.isFieldBase(); 42 | String fieldName = propertyArgDefinition.getName(); 43 | 44 | Class type = ClassUtil.getClass(typeStr); 45 | Object value = StringValueConverterFactory.convertValue(valueStr, type); 46 | 47 | if(fieldBase) { 48 | ReflectFieldUtil.setValue(instance, fieldName, value); 49 | } else { 50 | ReflectMethodUtil.invokeSetterMethod(instance, fieldName, value); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/registry/BeanDefinitionRegistry.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.registry; 2 | 3 | import com.github.houbb.ioc.model.BeanDefinition; 4 | 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | /** 9 | * 对象注册 10 | * 11 | * (1)该类的职责是负责对象的创建,不关心对应的 bean 的获取 12 | * 某种角度而言,这个类对于用户可以不那么可见。 13 | * 14 | * (2){@link com.github.houbb.ioc.core.BeanFactory} 更加关心对象的获取。 15 | * 16 | * @author binbin.hou 17 | * @since 0.1.8 18 | */ 19 | public interface BeanDefinitionRegistry { 20 | 21 | /** 22 | * Register a new bean definition with this registry. 23 | * Must support RootBeanDefinition and ChildBeanDefinition. 24 | * @param beanName the name of the bean instance to register 25 | * @param beanDefinition definition of the bean instance to register 26 | * or if there is already a BeanDefinition for the specified bean name 27 | * (and we are not allowed to override it) 28 | */ 29 | void registerBeanDefinition(String beanName, BeanDefinition beanDefinition); 30 | 31 | /** 32 | * Remove the BeanDefinition for the given name. 33 | * @param beanName the name of the bean instance to register 34 | */ 35 | void removeBeanDefinition(String beanName); 36 | 37 | /** 38 | * Return the BeanDefinition for the given bean name. 39 | * @param beanName name of the bean to find a definition for 40 | * @return the BeanDefinition for the given name (never {@code null}) 41 | */ 42 | BeanDefinition getBeanDefinition(String beanName); 43 | 44 | /** 45 | * Check if this registry contains a bean definition with the given name. 46 | * @param beanName the name of the bean to look for 47 | * @return if this registry contains a bean definition with the given name 48 | */ 49 | boolean containsBeanDefinition(String beanName); 50 | 51 | /** 52 | * Return the names of all beans defined in this registry. 53 | * @return the names of all beans defined in this registry, 54 | * or an empty array if none defined 55 | */ 56 | List getBeanDefinitionNames(); 57 | 58 | /** 59 | * Return the number of beans defined in the registry. 60 | * @return the number of beans defined in the registry 61 | */ 62 | int getBeanDefinitionCount(); 63 | 64 | /** 65 | * 根据类型获取对应的属性名称 66 | * 67 | * @param requiredType 需求类型 68 | * @return bean 名称列表 69 | * @since 0.0.2 初始化 70 | * @since 0.1.5 设置为公开方法 71 | */ 72 | Set getBeanNames(final Class requiredType); 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/registry/impl/DefaultBeanDefinitionRegistry.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.registry.impl; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.guava.Guavas; 5 | import com.github.houbb.heaven.util.lang.ObjectUtil; 6 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 7 | import com.github.houbb.heaven.util.util.ArrayUtil; 8 | import com.github.houbb.ioc.model.BeanDefinition; 9 | import com.github.houbb.ioc.support.lifecycle.registry.BeanDefinitionRegistry; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.Set; 15 | import java.util.concurrent.ConcurrentHashMap; 16 | 17 | /** 18 | * 对象注册 19 | * 20 | * (1)该类的职责是负责对象的创建,不关心对应的 bean 的获取 21 | * 某种角度而言,这个类对于用户可以不那么可见。 22 | * 23 | * (2){@link com.github.houbb.ioc.core.BeanFactory} 更加关心对象的获取。 24 | * 25 | * @author binbin.hou 26 | * @since 0.1.8 27 | */ 28 | public class DefaultBeanDefinitionRegistry implements BeanDefinitionRegistry { 29 | 30 | /** 31 | * 对象信息 map 32 | * 33 | * @since 0.0.1 34 | */ 35 | private Map beanDefinitionMap = new ConcurrentHashMap<>(); 36 | 37 | /** 38 | * 类型集合 39 | * (1)主要是为了 type 类型,获取对应的信息为做准备 40 | * (2)考虑到懒加载的处理。 41 | * 42 | * @since 0.0.2 43 | */ 44 | private Map> typeBeanNameMap = new ConcurrentHashMap<>(); 45 | 46 | @Override 47 | public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) { 48 | ArgUtil.notEmpty(beanName, "beanName"); 49 | ArgUtil.notNull(beanDefinition, "beanDefinition"); 50 | 51 | this.beanDefinitionMap.put(beanName, beanDefinition); 52 | this.registerTypeBeanNames(beanName, beanDefinition); 53 | } 54 | 55 | @Override 56 | public void removeBeanDefinition(String beanName) { 57 | this.beanDefinitionMap.remove(beanName); 58 | } 59 | 60 | @Override 61 | public BeanDefinition getBeanDefinition(String beanName) { 62 | return beanDefinitionMap.get(beanName); 63 | } 64 | 65 | @Override 66 | public boolean containsBeanDefinition(String beanName) { 67 | return beanDefinitionMap.containsKey(beanName); 68 | } 69 | 70 | @Override 71 | public List getBeanDefinitionNames() { 72 | Set nameSet = beanDefinitionMap.keySet(); 73 | return Guavas.newArrayList(nameSet); 74 | } 75 | 76 | @Override 77 | public int getBeanDefinitionCount() { 78 | return this.beanDefinitionMap.size(); 79 | } 80 | 81 | @Override 82 | public Set getBeanNames(Class requiredType) { 83 | ArgUtil.notNull(requiredType, "requiredType"); 84 | return typeBeanNameMap.get(requiredType); 85 | } 86 | 87 | /** 88 | * 注册类型和 beanNames 信息 89 | * 90 | * @param beanName 单个 bean 名称 91 | * @param beanDefinition 对象定义 92 | * @since 0.0.2 93 | */ 94 | private void registerTypeBeanNames(final String beanName, final BeanDefinition beanDefinition) { 95 | final Set typeSet = getTypeSet(beanDefinition); 96 | for (Class type : typeSet) { 97 | Set beanNameSet = typeBeanNameMap.get(type); 98 | if (ObjectUtil.isNull(beanNameSet)) { 99 | beanNameSet = Guavas.newHashSet(); 100 | } 101 | beanNameSet.add(beanName); 102 | typeBeanNameMap.put(type, beanNameSet); 103 | } 104 | } 105 | 106 | /** 107 | * 获取类型集合 108 | * (1)当前类信息 109 | * (2)递归所有的父类和接口类信息 110 | * 111 | * @param beanDefinition 对象定义 112 | * @return 类型集合 113 | * @since 0.0.8 114 | */ 115 | private Set getTypeSet(final BeanDefinition beanDefinition) { 116 | Set classSet = Guavas.newHashSet(); 117 | 118 | String className = beanDefinition.getClassName(); 119 | Class currentClass = ClassUtil.getClass(className); 120 | classSet.add(currentClass); 121 | 122 | classSet.addAll(ClassUtil.getAllInterfacesAndSuperClass(currentClass)); 123 | return classSet; 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/lifecycle/service/BeanLifecycleService.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.lifecycle.service; 2 | 3 | import com.github.houbb.ioc.core.BeanFactory; 4 | import com.github.houbb.ioc.model.BeanDefinition; 5 | import com.github.houbb.ioc.support.cycle.DependsCheckService; 6 | import com.github.houbb.ioc.support.lifecycle.DisposableBean; 7 | 8 | /** 9 | * 需要创建的单例对象 10 | * @author binbin.hou 11 | * @since 0.1.8 12 | */ 13 | public interface BeanLifecycleService extends DisposableBean { 14 | 15 | /** 16 | * 设置 bean 工厂属性 17 | * @param beanFactory bean 工厂 18 | * @since 0.1.8 19 | */ 20 | void setBeanFactory(final BeanFactory beanFactory); 21 | 22 | /** 23 | * 设置依赖检查服务类 24 | * @param dependsCheckService 实现类 25 | * @since 0.1.8 26 | */ 27 | void setDependsCheckService(final DependsCheckService dependsCheckService); 28 | 29 | /** 30 | * 创建需要创建的单例对象 31 | * 32 | * @param beanDefinition 对象定义 33 | * @since 0.1.5 34 | */ 35 | void createEagerSingleton(final BeanDefinition beanDefinition); 36 | 37 | /** 38 | * 注册单例且渴望初期初始化的对象 39 | * (1)如果是 singleton 且 lazy-init=false 则进行初始化处理 40 | * (2)创建完成后,对象放入 beanMap 中,便于后期使用 41 | * 42 | * @param beanName bean 名称 43 | * @param beanDefinition 对象定义 44 | * @since 0.0.3 45 | * @return 实例结果 46 | */ 47 | Object registerSingletonBean(final String beanName, final BeanDefinition beanDefinition); 48 | 49 | /** 50 | * 根据对象定义信息创建对象 51 | * (1)注解 {@link javax.annotation.PostConstruct} 52 | * (2)添加 {@link com.github.houbb.ioc.support.lifecycle.InitializingBean} 初始化相关处理 53 | * (3)添加 {@link BeanDefinition#getInitialize()} 初始化相关处理 54 | *

55 | * 如果想使用注解相关信息,考虑实现 AnnotationBeanDefinition 统一处理注解信息。 56 | * 本期暂时忽略 (1) 57 | * 58 | * @param beanDefinition 对象定义信息 59 | * @return 创建的对象信息 60 | * @since 0.0.1 61 | */ 62 | Object createBean(final BeanDefinition beanDefinition); 63 | 64 | /** 65 | * 注册单例对象 66 | * @param beanDefinition 对象定义信息 67 | * @param instance 对象实例 68 | * @since 0.1.10 69 | */ 70 | void registerSingletonBean(final BeanDefinition beanDefinition, final Object instance); 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/name/BeanNameStrategy.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.name; 2 | 3 | import com.github.houbb.ioc.model.BeanDefinition; 4 | 5 | /** 6 | * Bean 命名策略 7 | *

project: ioc-BeanNameStrategy

8 | *

create on 2019/11/19 22:39

9 | * 10 | * @author Administrator 11 | * @since 0.1.1 12 | */ 13 | public interface BeanNameStrategy { 14 | 15 | /** 16 | * 生成对象名称 17 | * @param definition bean 属性定义 18 | * @return 生成的结果名称 19 | * @since 0.1.1 20 | */ 21 | String generateBeanName(BeanDefinition definition); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/name/impl/DefaultBeanNameStrategy.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.name.impl; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.util.common.ArgUtil; 5 | import com.github.houbb.heaven.util.lang.StringUtil; 6 | import com.github.houbb.ioc.model.BeanDefinition; 7 | import com.github.houbb.ioc.support.name.BeanNameStrategy; 8 | 9 | /** 10 | * Bean 命名策略 11 | *

project: ioc-BeanNameStrategy

12 | *

create on 2019/11/19 22:39

13 | * 14 | * @author Administrator 15 | * @since 0.1.1 16 | */ 17 | @ThreadSafe 18 | public class DefaultBeanNameStrategy implements BeanNameStrategy { 19 | 20 | /** 21 | * 生成对象名称 22 | * (1)默认直接类名称首字母小写即可。 23 | * (2)如果已经指定 {@link BeanDefinition#getName()},则直接返回即可。 24 | * 25 | * @param definition bean 属性定义 26 | * @return 生成的结果名称 27 | * @since 0.1.1 28 | */ 29 | @Override 30 | public String generateBeanName(BeanDefinition definition) { 31 | final String name = definition.getName(); 32 | if(StringUtil.isNotEmpty(name)) { 33 | return name; 34 | } 35 | 36 | String className = definition.getClassName(); 37 | ArgUtil.notEmpty(className, "className"); 38 | String classSimpleName = className.substring(className.lastIndexOf(".")+1); 39 | return StringUtil.firstToLowerCase(classSimpleName); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/order/Order.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.order; 2 | 3 | /** 4 | * bean 的管理中经常会用到各种 order 的管理。 5 | *

project: ioc-Order

6 | *

create on 2019/11/12 23:14

7 | * 8 | * @author Administrator 9 | * @since 0.0.8 10 | */ 11 | public interface Order { 12 | 13 | /** 14 | * 获取指定的顺序 15 | * @return 顺序编号 16 | * @since 0.0.8 17 | */ 18 | int getOrder(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 相关功能支持类 3 | *

project: ioc-package-info

4 | *

create on 2019/11/8 20:51

5 | * 6 | * @author Administrator 7 | * @since 0.0.4 8 | */ 9 | package com.github.houbb.ioc.support; -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/processor/ApplicationContextPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.processor; 2 | 3 | import com.github.houbb.ioc.model.BeanDefinition; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * 用来标识可以修改的接口类 9 | *

project: ioc-Processor

10 | *

create on 2019/11/12 23:58

11 | * 12 | * @author Administrator 13 | * @since 0.0.8 14 | */ 15 | public interface ApplicationContextPostProcessor extends PostProcessor { 16 | 17 | /** 18 | * 对象属性注册之前 19 | * @param definitionList 对象原始定义信息列表 20 | * @return 结果 21 | * @since 0.0.8 22 | */ 23 | List beforeRegister(List definitionList); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/processor/BeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.processor; 2 | 3 | /** 4 | * 用来标识可以修改的接口类 5 | *

project: ioc-Processor

6 | *

create on 2019/11/12 23:58

7 | * 8 | * @author Administrator 9 | * @since 0.0.8 10 | */ 11 | public interface BeanPostProcessor extends PostProcessor { 12 | 13 | /** 14 | * 属性设置之前 15 | * @param beanName 对象名称 16 | * @param instance 实例 17 | * @return 结果 18 | * @since 0.0.8 19 | */ 20 | Object beforePropertySet(final String beanName, final Object instance); 21 | 22 | /** 23 | * 属性设置之后 24 | * @param beanName 对象名称 25 | * @param instance 实例 26 | * @return 结果 27 | * @since 0.0.8 28 | */ 29 | Object afterPropertySet(final String beanName, final Object instance); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/processor/PostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.processor; 2 | 3 | /** 4 | * 用来标识可以修改的接口类 5 | *

project: ioc-Processor

6 | *

create on 2019/11/12 23:58

7 | * 8 | * @author Administrator 9 | * @since 0.0.8 10 | */ 11 | public interface PostProcessor { 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/processor/impl/AutowiredAnnotationBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.processor.impl; 2 | 3 | import com.github.houbb.heaven.util.common.ArgUtil; 4 | import com.github.houbb.heaven.util.lang.reflect.ClassTypeUtil; 5 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 6 | import com.github.houbb.heaven.util.lang.reflect.ReflectFieldUtil; 7 | import com.github.houbb.heaven.util.lang.reflect.TypeUtil; 8 | import com.github.houbb.heaven.util.util.CollectionUtil; 9 | import com.github.houbb.ioc.annotation.Autowired; 10 | import com.github.houbb.ioc.core.BeanFactory; 11 | import com.github.houbb.ioc.core.ListableBeanFactory; 12 | import com.github.houbb.ioc.exception.IocRuntimeException; 13 | import com.github.houbb.ioc.support.aware.BeanFactoryAware; 14 | 15 | import java.lang.reflect.Field; 16 | import java.lang.reflect.Type; 17 | import java.util.Collection; 18 | import java.util.List; 19 | 20 | /** 21 | * 注解扫描中对于 {@link com.github.houbb.ioc.annotation.Autowired} 注解的处理 22 | * @author binbin.hou 23 | * @since 0.1.6 24 | */ 25 | public class AutowiredAnnotationBeanPostProcessor extends BeanPostProcessorAdaptor 26 | implements BeanFactoryAware { 27 | 28 | /** 29 | * 对象工厂 30 | * @since 0.1.6 31 | */ 32 | private BeanFactory beanFactory; 33 | 34 | @Override 35 | public void setBeanFactory(BeanFactory beanFactory) { 36 | this.beanFactory = beanFactory; 37 | } 38 | 39 | @Override 40 | @SuppressWarnings("unchecked") 41 | public Object afterPropertySet(String beanName, Object instance) { 42 | ArgUtil.notNull(instance, "instance"); 43 | 44 | final Class clazz = instance.getClass(); 45 | List fieldList = ClassUtil.getAllFieldList(clazz); 46 | 47 | ListableBeanFactory listableBeanFactory = (ListableBeanFactory)beanFactory; 48 | for(Field field : fieldList) { 49 | if(field.isAnnotationPresent(Autowired.class)) { 50 | Autowired autowired = field.getAnnotation(Autowired.class); 51 | 52 | // 这里可以添加计算,如果是集合,那么返回集合 53 | final Class fieldTypeClass = field.getType(); 54 | final String value = autowired.value(); 55 | Object fieldRefValue; 56 | 57 | // 集合特殊处理 58 | if(ClassTypeUtil.isCollection(fieldTypeClass)) { 59 | final Type fieldGenericType = field.getGenericType(); 60 | Class itemClass = TypeUtil.getGenericType(fieldGenericType); 61 | List list = listableBeanFactory.getBeans(itemClass); 62 | if(CollectionUtil.isEmpty(list)) { 63 | throw new IocRuntimeException("Autowired of class type " + itemClass 64 | +" not found!"); 65 | } 66 | Collection collection = TypeUtil.createCollection(fieldGenericType); 67 | collection.addAll(list); 68 | fieldRefValue = collection; 69 | } else { 70 | fieldRefValue = listableBeanFactory.getRequiredTypeBean(fieldTypeClass, value); 71 | } 72 | 73 | ReflectFieldUtil.setValue(field, instance, fieldRefValue); 74 | } 75 | } 76 | 77 | return instance; 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/processor/impl/BeanPostProcessorAdaptor.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.processor.impl; 2 | 3 | import com.github.houbb.ioc.support.processor.BeanPostProcessor; 4 | 5 | /** 6 | * 用来标识可以修改的接口类 7 | *

project: ioc-Processor

8 | *

create on 2019/11/12 23:58

9 | * 10 | * @author Administrator 11 | * @since 0.0.8 12 | */ 13 | public class BeanPostProcessorAdaptor implements BeanPostProcessor { 14 | 15 | /** 16 | * 属性设置之前 17 | * @param beanName 对象名称 18 | * @param instance 实例 19 | * @return 结果 20 | * @since 0.0.8 21 | */ 22 | @Override 23 | public Object beforePropertySet(final String beanName, final Object instance) { 24 | return instance; 25 | } 26 | 27 | /** 28 | * 属性设置之后 29 | * @param beanName 对象名称 30 | * @param instance 实例 31 | * @return 结果 32 | * @since 0.0.8 33 | */ 34 | @Override 35 | public Object afterPropertySet(final String beanName, final Object instance) { 36 | return instance; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/scanner/AnnotationBeanDefinitionScanner.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.scanner; 2 | 3 | import com.github.houbb.ioc.model.AnnotationBeanDefinition; 4 | import com.github.houbb.ioc.model.BeanDefinition; 5 | 6 | import java.util.Set; 7 | 8 | /** 9 | *

project: ioc-BeanDefinitionScanner

10 | *

create on 2019/11/18 20:38

11 | * 12 | * @author Administrator 13 | * @since 0.1.11 14 | * @see com.github.houbb.ioc.annotation.ComponentScan 包扫描 15 | * @see com.github.houbb.ioc.annotation.Component 组件注解 16 | */ 17 | public interface AnnotationBeanDefinitionScanner { 18 | 19 | /** 20 | * 扫描指定的包,返回对应的 {@link AnnotationBeanDefinition} 信息集合 21 | * @param context 上下文 22 | * @return 结果列表 23 | * @since 0.1.11 24 | */ 25 | Set scan(final BeanDefinitionScannerContext context); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/scanner/BeanDefinitionScannerContext.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.scanner; 2 | 3 | import com.github.houbb.ioc.support.name.BeanNameStrategy; 4 | 5 | import java.lang.annotation.Annotation; 6 | import java.util.List; 7 | 8 | /** 9 | * 扫描上下文 10 | *

project: ioc-BeanDefinitionScanner

11 | *

create on 2019/11/18 20:38

12 | * 13 | * @author Administrator 14 | * @since 0.1.11 15 | * @see com.github.houbb.ioc.annotation.ComponentScan 包扫描 16 | * @see com.github.houbb.ioc.annotation.Component 组件注解 17 | */ 18 | public interface BeanDefinitionScannerContext { 19 | 20 | /** 21 | * 获取需要扫描的包列表 22 | * @return 包 23 | * @since 0.1.11 24 | */ 25 | List getScanPackages(); 26 | 27 | /** 28 | * 获取所有需要排除的类列表 29 | * @return 类列表 30 | * @since 0.1.11 31 | */ 32 | List getExcludes(); 33 | 34 | /** 35 | * 获取所有需要包含的类列表 36 | * @return 类列表 37 | * @since 0.1.11 38 | */ 39 | List getIncludes(); 40 | 41 | /** 42 | * 获取对象名称策略 43 | * @return 名称策略类 44 | * @since 0.1.11 45 | */ 46 | Class getBeanNameStrategy(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/scanner/TypeFilter.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.scanner; 2 | 3 | import com.github.houbb.heaven.reflect.meta.annotation.IAnnotationTypeMeta; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | *

project: ioc-TypeIncludeFilter

9 | *

create on 2019/12/1 11:18

10 | * 11 | * @author Administrator 12 | * @since 0.1.11 13 | */ 14 | public interface TypeFilter { 15 | 16 | /** 17 | * 是否匹配 18 | * @param clazz 类信息 19 | * @param typeMeta 注解元数据信息 20 | * @param classList 类类表 21 | * @return 结果 22 | * @since 0.1.11 23 | */ 24 | boolean matches(final Class clazz, final IAnnotationTypeMeta typeMeta, final List classList); 25 | 26 | } -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/scanner/impl/AnnotatedTypeFilter.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.scanner.impl; 2 | 3 | import com.github.houbb.heaven.annotation.ThreadSafe; 4 | import com.github.houbb.heaven.reflect.meta.annotation.IAnnotationTypeMeta; 5 | import com.github.houbb.ioc.support.scanner.TypeFilter; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | *

project: ioc-AnnotatedTypeFilter

11 | *

create on 2019/12/1 12:52

12 | * 13 | * @author Administrator 14 | * @since 0.1.11 15 | */ 16 | @ThreadSafe 17 | public class AnnotatedTypeFilter implements TypeFilter { 18 | 19 | @Override 20 | public boolean matches(Class clazz, IAnnotationTypeMeta typeMeta, List classList) { 21 | return typeMeta.isAnnotatedOrRef(classList); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/houbb/ioc/support/scanner/impl/DefaultBeanDefinitionScannerContext.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.support.scanner.impl; 2 | 3 | import com.github.houbb.ioc.support.name.BeanNameStrategy; 4 | import com.github.houbb.ioc.support.scanner.BeanDefinitionScannerContext; 5 | 6 | import java.lang.annotation.Annotation; 7 | import java.util.List; 8 | 9 | /** 10 | *

project: ioc-DefaultBeanDefinitionScannerContext

11 | *

create on 2019/12/1 12:48

12 | * 13 | * @author Administrator 14 | * @since 0.1.11 15 | */ 16 | public class DefaultBeanDefinitionScannerContext implements BeanDefinitionScannerContext { 17 | 18 | /** 19 | * 获取需要扫描的包列表 20 | * @since 0.1.11 21 | */ 22 | private List scanPackages; 23 | 24 | /** 25 | * 获取所有需要排除的类列表 26 | * @since 0.1.11 27 | */ 28 | private List excludes; 29 | 30 | /** 31 | * 获取所有需要包含的类列表 32 | * @since 0.1.11 33 | */ 34 | private List includes; 35 | 36 | /** 37 | * 获取对象名称策略 38 | * @since 0.1.11 39 | */ 40 | private Class beanNameStrategy; 41 | 42 | @Override 43 | public List getScanPackages() { 44 | return scanPackages; 45 | } 46 | 47 | public void setScanPackages(List scanPackages) { 48 | this.scanPackages = scanPackages; 49 | } 50 | 51 | @Override 52 | public List getExcludes() { 53 | return excludes; 54 | } 55 | 56 | public void setExcludes(List excludes) { 57 | this.excludes = excludes; 58 | } 59 | 60 | @Override 61 | public List getIncludes() { 62 | return includes; 63 | } 64 | 65 | public void setIncludes(List includes) { 66 | this.includes = includes; 67 | } 68 | 69 | @Override 70 | public Class getBeanNameStrategy() { 71 | return beanNameStrategy; 72 | } 73 | 74 | public void setBeanNameStrategy(Class beanNameStrategy) { 75 | this.beanNameStrategy = beanNameStrategy; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppAutowiredCollectionConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.heaven.util.guava.Guavas; 4 | import com.github.houbb.ioc.annotation.Autowired; 5 | import com.github.houbb.ioc.annotation.Configuration; 6 | import com.github.houbb.ioc.annotation.Import; 7 | import com.github.houbb.ioc.test.model.Book; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

project: ioc-AppConfig

13 | *

create on 2019/11/19 23:01

14 | * 15 | * @author Administrator 16 | * @since 0.1.6 17 | */ 18 | @Configuration 19 | @Import(AppMultiBeanConfig.class) 20 | public class AppAutowiredCollectionConfig { 21 | 22 | /** 23 | * 彩色书籍列表 24 | * @since 0.1.6 25 | */ 26 | @Autowired 27 | private List bookList; 28 | 29 | /** 30 | * 获取苹果彩色列表 31 | * @return 列表 32 | * @since 0.1.6 33 | */ 34 | public List getAppleColorList() { 35 | List bookNameList = Guavas.newArrayList(); 36 | 37 | for(Book book : bookList) { 38 | bookNameList.add(book.getName()); 39 | } 40 | return bookNameList; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppAutowiredConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Autowired; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.annotation.Import; 6 | import com.github.houbb.ioc.test.service.WeightApple; 7 | 8 | /** 9 | *

project: ioc-AppConfig

10 | *

create on 2019/11/19 23:01

11 | * 12 | * Autowired 13 | * @author Administrator 14 | * @since 0.1.6 15 | */ 16 | @Configuration 17 | @Import(AppBeanConfig.class) 18 | public class AppAutowiredConfig { 19 | 20 | @Autowired 21 | private WeightApple weightApple; 22 | 23 | /** 24 | * 展示重量 25 | * @since 0.1.6 26 | * @return 重量 27 | */ 28 | public String getWeight() { 29 | return weightApple.getWeight(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppAutowiredEnvConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Autowired; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.annotation.Import; 6 | import com.github.houbb.ioc.support.envrionment.Environment; 7 | import com.github.houbb.ioc.test.service.WeightApple; 8 | 9 | /** 10 | *

project: ioc-AppConfig

11 | *

create on 2019/11/19 23:01

12 | * 13 | * @author Administrator 14 | * @since 0.1.9 15 | */ 16 | @Configuration 17 | public class AppAutowiredEnvConfig { 18 | 19 | @Autowired 20 | private Environment environment; 21 | 22 | /** 23 | * 展示环境信息 24 | * @since 0.1.9 25 | * @return 环境信息 26 | */ 27 | public String[] getProfiles() { 28 | return environment.getActiveProfiles(); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppAutowiredPrimaryConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Autowired; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.annotation.Import; 6 | import com.github.houbb.ioc.test.model.Book; 7 | import com.github.houbb.ioc.test.service.WeightApple; 8 | 9 | /** 10 | *

project: ioc-AppConfig

11 | *

create on 2019/11/19 23:01

12 | * 13 | * @author Administrator 14 | * @since 0.1.7 15 | */ 16 | @Configuration 17 | @Import(AppMultiBeanConfig.class) 18 | public class AppAutowiredPrimaryConfig { 19 | 20 | @Autowired 21 | private Book book; 22 | 23 | /** 24 | * 返回书籍 25 | * @return 书籍 26 | * @since 0.1.7 27 | */ 28 | public Book getBook() { 29 | return book; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppBeanConditionConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Bean; 4 | import com.github.houbb.ioc.annotation.Conditional; 5 | import com.github.houbb.ioc.annotation.Configuration; 6 | import com.github.houbb.ioc.annotation.Primary; 7 | import com.github.houbb.ioc.test.model.Book; 8 | import com.github.houbb.ioc.test.support.condition.FalseCondition; 9 | import com.github.houbb.ioc.test.support.condition.TrueCondition; 10 | 11 | /** 12 | *

project: ioc-AppConfig

13 | *

create on 2019/11/19 23:01

14 | * 15 | * @author Administrator 16 | * @since 0.1.8 17 | */ 18 | @Configuration 19 | public class AppBeanConditionConfig { 20 | 21 | @Bean 22 | @Conditional(FalseCondition.class) 23 | public Book book() { 24 | return new Book("good"); 25 | } 26 | 27 | @Bean 28 | @Conditional(TrueCondition.class) 29 | public Book book2() { 30 | return new Book("bad"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppBeanConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Bean; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.test.service.Apple; 6 | import com.github.houbb.ioc.test.service.WeightApple; 7 | 8 | /** 9 | *

project: ioc-AppConfig

10 | *

create on 2019/11/19 23:01

11 | * 12 | * @author Administrator 13 | * @since 0.1.2 14 | */ 15 | @Configuration 16 | public class AppBeanConfig { 17 | 18 | @Bean 19 | public WeightApple weightApple() { 20 | return new WeightApple(); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppBeanLazyScopeConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Bean; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.annotation.Lazy; 6 | import com.github.houbb.ioc.annotation.Scope; 7 | import com.github.houbb.ioc.constant.ScopeConst; 8 | import com.github.houbb.ioc.test.service.Apple; 9 | import com.github.houbb.ioc.test.service.WeightApple; 10 | 11 | /** 12 | *

project: ioc-AppConfig

13 | *

create on 2019/11/19 23:01

14 | * 15 | * @author Administrator 16 | * @since 0.1.3 17 | */ 18 | @Configuration 19 | public class AppBeanLazyScopeConfig { 20 | 21 | @Bean 22 | public WeightApple weightApple() { 23 | return new WeightApple(); 24 | } 25 | 26 | /** 27 | * 设置为懒加载多例 28 | * @return 结果 29 | * @since 0.1.3 30 | */ 31 | @Bean 32 | @Scope(ScopeConst.PROTOTYPE) 33 | @Lazy(true) 34 | public Apple apple() { 35 | return new Apple(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppBeanProfileConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Bean; 4 | import com.github.houbb.ioc.annotation.Conditional; 5 | import com.github.houbb.ioc.annotation.Configuration; 6 | import com.github.houbb.ioc.annotation.Profile; 7 | import com.github.houbb.ioc.constant.ProfileConst; 8 | import com.github.houbb.ioc.support.condition.impl.ProfileCondition; 9 | import com.github.houbb.ioc.test.model.Book; 10 | import com.github.houbb.ioc.test.support.condition.FalseCondition; 11 | import com.github.houbb.ioc.test.support.condition.TrueCondition; 12 | 13 | /** 14 | *

project: ioc-AppConfig

15 | *

create on 2019/11/19 23:01

16 | * 17 | * @author Administrator 18 | * @since 0.1.9 19 | */ 20 | @Configuration 21 | @Profile({ProfileConst.DEV, ProfileConst.TEST}) 22 | public class AppBeanProfileConfig { 23 | 24 | @Bean 25 | @Profile({ProfileConst.DEV}) 26 | public Book devBook() { 27 | return new Book("devBook"); 28 | } 29 | 30 | @Bean 31 | @Profile({ProfileConst.TEST}) 32 | public Book testBook() { 33 | return new Book("testBook"); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppBeanRefConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Bean; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.test.model.Book; 6 | import com.github.houbb.ioc.test.model.User; 7 | import com.github.houbb.ioc.test.service.WeightApple; 8 | 9 | /** 10 | *

project: ioc-AppConfig

11 | *

create on 2019/11/19 23:01

12 | * 13 | * @author Administrator 14 | * @since 0.1.5 15 | */ 16 | @Configuration 17 | public class AppBeanRefConfig { 18 | 19 | @Bean 20 | public Book book() { 21 | Book book = new Book(); 22 | book.setName("《海底两万里》"); 23 | return book; 24 | } 25 | 26 | @Bean 27 | public User user(final Book book) { 28 | User user = new User(); 29 | user.setName("Hello"); 30 | user.setBook(book); 31 | return user; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppComponentScanConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.ComponentScan; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | 6 | /** 7 | *

project: ioc-AppConfig

8 | *

create on 2019/11/19 23:01

9 | * 10 | * @author Administrator 11 | * @since 0.1.11 12 | */ 13 | @Configuration 14 | @ComponentScan("com.github.houbb.ioc.test.service.inner") 15 | public class AppComponentScanConfig { 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppComponentScanFilterConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.ComponentScan; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.annotation.Service; 6 | 7 | /** 8 | * 排除 service 指定的属性 9 | *

project: ioc-AppConfig

10 | *

create on 2019/11/19 23:01

11 | * 12 | * @author Administrator 13 | * @since 0.1.11 14 | */ 15 | @Configuration 16 | @ComponentScan(value = "com.github.houbb.ioc.test.service.inner", excludes = Service.class) 17 | public class AppComponentScanFilterConfig { 18 | } 19 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Configuration; 4 | 5 | /** 6 | *

project: ioc-AppConfig

7 | *

create on 2019/11/19 23:01

8 | * 9 | * @author Administrator 10 | * @since 0.1.1 11 | */ 12 | @Configuration 13 | public class AppConfig { 14 | 15 | public String name() { 16 | return "app config"; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppImportConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Import; 4 | 5 | /** 6 | *

project: ioc-AppConfig

7 | *

create on 2019/11/19 23:01

8 | * 9 | * @author Administrator 10 | * @since 0.1.4 11 | */ 12 | @Import(AppBeanConfig.class) 13 | public class AppImportConfig { 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppMultiBeanConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Bean; 4 | import com.github.houbb.ioc.annotation.Configuration; 5 | import com.github.houbb.ioc.annotation.Primary; 6 | import com.github.houbb.ioc.test.model.Book; 7 | import com.github.houbb.ioc.test.service.ColorApple; 8 | import com.github.houbb.ioc.test.service.WeightApple; 9 | 10 | /** 11 | *

project: ioc-AppConfig

12 | *

create on 2019/11/19 23:01

13 | * 14 | * @author Administrator 15 | * @since 0.1.6 16 | */ 17 | @Configuration 18 | public class AppMultiBeanConfig { 19 | 20 | /** 21 | * @since 0.1.7 指定优先级 22 | * @return 书籍信息 23 | */ 24 | @Bean 25 | @Primary 26 | public Book book() { 27 | return new Book("good"); 28 | } 29 | 30 | @Bean 31 | public Book book2() { 32 | return new Book("bad"); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppPropertyResourceValueConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Configuration; 4 | import com.github.houbb.ioc.annotation.PropertiesResource; 5 | import com.github.houbb.ioc.annotation.Value; 6 | 7 | /** 8 | *

project: ioc-AppConfig

9 | *

create on 2019/11/19 23:01

10 | * 11 | * @author Administrator 12 | * @since 0.1.10 13 | */ 14 | @Configuration 15 | @PropertiesResource("name.properties") 16 | public class AppPropertyResourceValueConfig { 17 | 18 | /** 19 | * 名称 20 | * @since 0.1.10 21 | */ 22 | @Value("${name:ryo}") 23 | private String name; 24 | 25 | public String getName() { 26 | return this.name; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/AppPropertyValueConfig.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.config; 2 | 3 | import com.github.houbb.ioc.annotation.Configuration; 4 | import com.github.houbb.ioc.annotation.Value; 5 | 6 | /** 7 | *

project: ioc-AppConfig

8 | *

create on 2019/11/19 23:01

9 | * 10 | * @author Administrator 11 | * @since 0.1.10 12 | */ 13 | @Configuration 14 | public class AppPropertyValueConfig { 15 | 16 | /** 17 | * 名称 18 | * @since 0.1.10 19 | */ 20 | @Value("${name:ryo}") 21 | private String name; 22 | 23 | public String getName() { 24 | return this.name; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/config/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | *

project: ioc-package-info

3 | *

create on 2019/11/19 23:01

4 | * 5 | * @author Administrator 6 | * @since 1.0.0 7 | */ 8 | package com.github.houbb.ioc.test.config; -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/context/ConfigBeanApplicationContextTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.context; 2 | 3 | import com.github.houbb.ioc.context.AnnotationApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.test.config.AppBeanConfig; 6 | import com.github.houbb.ioc.test.config.AppBeanRefConfig; 7 | import com.github.houbb.ioc.test.config.AppConfig; 8 | import com.github.houbb.ioc.test.model.User; 9 | import com.github.houbb.ioc.test.service.Apple; 10 | import com.github.houbb.ioc.test.service.WeightApple; 11 | import org.junit.Assert; 12 | import org.junit.Test; 13 | 14 | /** 15 | *

project: ioc-JsonApplicationContextTest

16 | *

create on 2019/11/6 20:09

17 | * 18 | * @author Administrator 19 | * @since 0.1.2 20 | */ 21 | public class ConfigBeanApplicationContextTest { 22 | 23 | /** 24 | * 实现最基本的 Config-bean 测试 25 | * @since 0.1.2 26 | */ 27 | @Test 28 | public void weightAppleTest() { 29 | BeanFactory beanFactory = new AnnotationApplicationContext(AppBeanConfig.class); 30 | WeightApple apple = beanFactory.getBean("weightApple", WeightApple.class); 31 | 32 | Assert.assertEquals("10", apple.getWeight()); 33 | } 34 | 35 | /** 36 | * 对象引用其他对象测试 37 | * @since 0.1.5 38 | */ 39 | @Test 40 | public void beanRefTest() { 41 | BeanFactory beanFactory = new AnnotationApplicationContext(AppBeanRefConfig.class); 42 | User user = beanFactory.getBean("user", User.class); 43 | 44 | Assert.assertEquals("User{book=Book{name='《海底两万里》'}, name='Hello'}", user.toString()); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/context/ConfigBeanLazyScopeAppCtxTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.context; 2 | 3 | import com.github.houbb.ioc.context.AnnotationApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.test.config.AppBeanConfig; 6 | import com.github.houbb.ioc.test.config.AppBeanLazyScopeConfig; 7 | import com.github.houbb.ioc.test.service.Apple; 8 | import com.github.houbb.ioc.test.service.WeightApple; 9 | import org.junit.Assert; 10 | import org.junit.Test; 11 | 12 | /** 13 | *

project: ioc-JsonApplicationContextTest

14 | *

create on 2019/11/6 20:09

15 | * 16 | * @author Administrator 17 | * @since 0.1.3 18 | */ 19 | public class ConfigBeanLazyScopeAppCtxTest { 20 | 21 | /** 22 | * 添加 scope lazy-init 测试 23 | * @since 0.1.3 24 | */ 25 | @Test 26 | public void weightAppleTest() { 27 | BeanFactory beanFactory = new AnnotationApplicationContext(AppBeanLazyScopeConfig.class); 28 | WeightApple weightAppleOne = beanFactory.getBean("weightApple", WeightApple.class); 29 | WeightApple weightAppleTwo = beanFactory.getBean("weightApple", WeightApple.class); 30 | Assert.assertSame(weightAppleOne, weightAppleTwo); 31 | 32 | Apple appleOne = beanFactory.getBean("apple", Apple.class); 33 | Apple appleTwo = beanFactory.getBean("apple", Apple.class); 34 | Assert.assertNotSame(appleOne, appleTwo); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/context/ConfigImportAppCtxTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.context; 2 | 3 | import com.github.houbb.ioc.context.AnnotationApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.test.config.AppImportConfig; 6 | import com.github.houbb.ioc.test.service.WeightApple; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | /** 11 | *

project: ioc-JsonApplicationContextTest

12 | *

create on 2019/11/6 20:09

13 | * 14 | * @author Administrator 15 | * @since 0.1.4 16 | */ 17 | public class ConfigImportAppCtxTest { 18 | 19 | /** 20 | * 添加 @Import 支持 21 | * @since 0.1.4 22 | */ 23 | @Test 24 | public void importTest() { 25 | BeanFactory beanFactory = new AnnotationApplicationContext(AppImportConfig.class); 26 | WeightApple weightApple = beanFactory.getBean("weightApple", WeightApple.class); 27 | 28 | Assert.assertEquals("10", weightApple.getWeight()); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/context/JsonApplicationContextTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.context; 2 | 3 | import com.github.houbb.ioc.context.JsonApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.test.service.Apple; 6 | import org.junit.Test; 7 | 8 | /** 9 | *

project: ioc-JsonApplicationContextTest

10 | *

create on 2019/11/6 20:09

11 | * 12 | * @author Administrator 13 | * @since 0.0.1 14 | */ 15 | @Deprecated 16 | public class JsonApplicationContextTest { 17 | 18 | @Test 19 | public void simpleTest() { 20 | BeanFactory beanFactory = new JsonApplicationContext("apple.json"); 21 | Apple apple = beanFactory.getBean("apple", Apple.class); 22 | apple.color(); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/BeanFactoryTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.heaven.util.guava.Guavas; 4 | import com.github.houbb.ioc.context.JsonApplicationContext; 5 | import com.github.houbb.ioc.core.BeanFactory; 6 | import com.github.houbb.ioc.model.BeanDefinition; 7 | import com.github.houbb.ioc.model.impl.DefaultBeanDefinition; 8 | import com.github.houbb.ioc.test.service.Apple; 9 | import com.github.houbb.json.bs.JsonBs; 10 | import org.junit.Assert; 11 | import org.junit.Test; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * @author binbin.hou 17 | * @since 0.0.2 18 | */ 19 | public class BeanFactoryTest { 20 | 21 | /** 22 | * bean 工厂 23 | * @since 0.0.2 24 | */ 25 | private static final BeanFactory BEAN_FACTORY = new JsonApplicationContext("apple.json"); 26 | 27 | 28 | /** 29 | * 测试 30 | * @since 0.0.1 31 | */ 32 | @Test 33 | public void getBeanByNameTest() { 34 | BeanFactory beanFactory = new JsonApplicationContext("apple.json"); 35 | Apple apple = (Apple) beanFactory.getBean("apple"); 36 | apple.color(); 37 | } 38 | 39 | /** 40 | * 测试 41 | * @since 0.0.2 42 | */ 43 | @Test 44 | public void getBeanByNameTypeTest() { 45 | Apple apple = BEAN_FACTORY.getBean("apple", Apple.class); 46 | apple.color(); 47 | } 48 | 49 | /** 50 | * 测试 51 | * @since 0.0.2 52 | */ 53 | @Test 54 | public void containsBeanTest() { 55 | Assert.assertTrue(BEAN_FACTORY.containsBean("apple")); 56 | Assert.assertFalse(BEAN_FACTORY.containsBean("box")); 57 | } 58 | 59 | /** 60 | * 测试 61 | * @since 0.0.2 62 | */ 63 | @Test 64 | public void isTypeMatchTest() { 65 | Assert.assertTrue(BEAN_FACTORY.isTypeMatch("apple", Apple.class)); 66 | Assert.assertFalse(BEAN_FACTORY.isTypeMatch("apple", BeanFactory.class)); 67 | } 68 | 69 | /** 70 | * 单例测试 71 | * @since 0.0.3 72 | */ 73 | @Test 74 | public void singletonTest() { 75 | BeanFactory singleton = new JsonApplicationContext("singleton/apple-singleton.json"); 76 | 77 | Apple singletonOne = singleton.getBean("apple", Apple.class); 78 | Apple singletonTwo = singleton.getBean("apple", Apple.class); 79 | Assert.assertSame(singletonOne, singletonTwo); 80 | } 81 | 82 | // /** 83 | // * 多例测试 84 | // * @since 0.0.3 85 | // */ 86 | // @Test 87 | // public void prototypeTest() { 88 | // final String config = "singleton/apple-prototype.js111on"; 89 | // BeanFactory singleton = new JsonApplicationContext(config); 90 | // 91 | // Apple singletonOne = singleton.getBean("apple", Apple.class); 92 | // Apple singletonTwo = singleton.getBean("apple", Apple.class); 93 | // 94 | // Assert.assertNotSame(singletonOne, singletonTwo); 95 | // } 96 | 97 | 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/BeanPropertyTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.heaven.util.guava.Guavas; 4 | import com.github.houbb.ioc.context.JsonApplicationContext; 5 | import com.github.houbb.ioc.core.BeanFactory; 6 | import com.github.houbb.ioc.model.BeanDefinition; 7 | import com.github.houbb.ioc.model.ConstructorArgDefinition; 8 | import com.github.houbb.ioc.model.PropertyArgDefinition; 9 | import com.github.houbb.ioc.model.impl.DefaultBeanDefinition; 10 | import com.github.houbb.ioc.model.impl.DefaultConstructorArgDefinition; 11 | import com.github.houbb.ioc.model.impl.DefaultPropertyArgDefinition; 12 | import com.github.houbb.ioc.test.model.User; 13 | import com.github.houbb.ioc.test.service.Apple; 14 | import com.github.houbb.json.bs.JsonBs; 15 | import org.junit.Ignore; 16 | import org.junit.Test; 17 | 18 | import java.util.Arrays; 19 | import java.util.List; 20 | 21 | /** 22 | * @author binbin.hou 23 | * @since 0.0.6 24 | */ 25 | public class BeanPropertyTest { 26 | 27 | /** 28 | * 生成 apple json 测试 29 | * @since 0.0.6 30 | */ 31 | @Test 32 | @Ignore 33 | public void genUserJsonTest() { 34 | List beanDefinitions = Guavas.newArrayList(); 35 | BeanDefinition book = new DefaultBeanDefinition(); 36 | book.setName("book"); 37 | book.setClassName("com.github.houbb.ioc.test.model.Book"); 38 | beanDefinitions.add(book); 39 | 40 | BeanDefinition user = new DefaultBeanDefinition(); 41 | user.setName("user"); 42 | user.setClassName("com.github.houbb.ioc.test.model.User"); 43 | 44 | PropertyArgDefinition userNameArgDefinition = new DefaultPropertyArgDefinition(); 45 | userNameArgDefinition.setName("name"); 46 | userNameArgDefinition.setValue("helen"); 47 | userNameArgDefinition.setType("java.lang.String"); 48 | 49 | PropertyArgDefinition userBookArgDefinition = new DefaultPropertyArgDefinition(); 50 | userBookArgDefinition.setName("book"); 51 | userBookArgDefinition.setRef("book"); 52 | user.setPropertyArgList(Arrays.asList(userNameArgDefinition, userBookArgDefinition)); 53 | beanDefinitions.add(user); 54 | 55 | String json = JsonBs.serialize(beanDefinitions); 56 | System.out.println(json); 57 | } 58 | 59 | /** 60 | * 对象属性测试 61 | * @since 0.0.7 62 | */ 63 | @Test 64 | public void beanPropertyTest() { 65 | BeanFactory beanFactory = new JsonApplicationContext("property/user-property.json"); 66 | User user = beanFactory.getBean("user", User.class); 67 | System.out.println(user); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/CircleTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.ioc.context.JsonApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.exception.IocRuntimeException; 6 | import com.github.houbb.ioc.test.model.User; 7 | import com.github.houbb.ioc.test.service.ColorWeightApple; 8 | import org.junit.Assert; 9 | import org.junit.Test; 10 | 11 | /** 12 | * 循环依赖测试 13 | * @author binbin.hou 14 | * @since 0.1.0 15 | */ 16 | public class CircleTest { 17 | 18 | /** 19 | * a-b 直接互相依赖 20 | * @since 0.1.0 21 | */ 22 | @Test(expected = IocRuntimeException.class) 23 | public void directCircleTest() { 24 | final BeanFactory beanFactory = new JsonApplicationContext("circle/direct-circle.json"); 25 | ColorWeightApple apple = beanFactory.getBean("weightApple", ColorWeightApple.class); 26 | } 27 | 28 | /** 29 | * a-b 30 | * b-c 31 | * c-a 32 | * 33 | * 间接循环依赖 34 | * @since 0.1.0 35 | */ 36 | @Test(expected = IocRuntimeException.class) 37 | public void inDirectCircleTest() { 38 | final BeanFactory beanFactory = new JsonApplicationContext("circle/in-direct-circle.json"); 39 | ColorWeightApple apple = beanFactory.getBean("weightApple", ColorWeightApple.class); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/GenJsonTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.heaven.util.guava.Guavas; 4 | import com.github.houbb.ioc.model.BeanDefinition; 5 | import com.github.houbb.ioc.model.ConstructorArgDefinition; 6 | import com.github.houbb.ioc.model.impl.DefaultBeanDefinition; 7 | import com.github.houbb.ioc.model.impl.DefaultConstructorArgDefinition; 8 | import com.github.houbb.json.bs.JsonBs; 9 | import org.junit.Ignore; 10 | import org.junit.Test; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | /** 16 | * @author binbin.hou 17 | * @since 0.0.6 18 | */ 19 | public class GenJsonTest { 20 | 21 | /** 22 | * 生成 apple json 测试 23 | * @since 0.0.1 24 | */ 25 | @Test 26 | @Ignore 27 | public void genAppleJsonTest() { 28 | List beanDefinitions = Guavas.newArrayList(); 29 | BeanDefinition weightApple = new DefaultBeanDefinition(); 30 | weightApple.setName("weightApple"); 31 | weightApple.setClassName("com.github.houbb.ioc.test.service.ColorWeightApple"); 32 | 33 | ConstructorArgDefinition argRef = new DefaultConstructorArgDefinition(); 34 | argRef.setRef("apple"); 35 | 36 | ConstructorArgDefinition argWeight = new DefaultConstructorArgDefinition(); 37 | argWeight.setType("java.lang.Integer"); 38 | argWeight.setValue("10"); 39 | 40 | weightApple.setConstructorArgList(Arrays.asList(argRef, argWeight)); 41 | beanDefinitions.add(weightApple); 42 | 43 | BeanDefinition apple = new DefaultBeanDefinition(); 44 | apple.setName("apple"); 45 | apple.setClassName("com.github.houbb.ioc.test.service.ColorApple"); 46 | beanDefinitions.add(apple); 47 | 48 | String json = JsonBs.serialize(beanDefinitions); 49 | System.out.println(json); 50 | 51 | System.out.println("==========================="); 52 | 53 | System.out.println(JsonBs.deserializeArray(json, BeanDefinition.class)); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/InitTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.ioc.context.JsonApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.test.service.Apple; 6 | import org.junit.Test; 7 | 8 | /** 9 | * @author binbin.hou 10 | * @since 0.0.4 11 | */ 12 | public class InitTest { 13 | 14 | /** 15 | * 测试 16 | * @since 0.0.4 17 | */ 18 | @Test 19 | public void postConstructTest() throws InterruptedException { 20 | BeanFactory beanFactory = new JsonApplicationContext("apple.json"); 21 | Apple apple = (Apple) beanFactory.getBean("apple"); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/ListableBeanFactoryTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.ioc.context.JsonApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.core.ListableBeanFactory; 6 | import com.github.houbb.ioc.core.impl.DefaultBeanFactory; 7 | import com.github.houbb.ioc.test.service.Apple; 8 | import org.junit.Assert; 9 | import org.junit.Test; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * @author binbin.hou 15 | * @since 0.0.2 16 | */ 17 | public class ListableBeanFactoryTest { 18 | 19 | /** 20 | * bean 工厂 21 | * @since 0.0.2 22 | */ 23 | private static final ListableBeanFactory BEAN_FACTORY = new JsonApplicationContext("apples.json"); 24 | 25 | /** 26 | * 测试 27 | * @since 0.0.2 28 | */ 29 | @Test 30 | public void getBeansTest() { 31 | List appleList = BEAN_FACTORY.getBeans(Apple.class); 32 | appleList.get(0).color(); 33 | appleList.get(1).color(); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/NewInstanceTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.ioc.context.JsonApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.test.service.Apple; 6 | import com.github.houbb.ioc.test.service.ColorApple; 7 | import com.github.houbb.ioc.test.service.ColorWeightApple; 8 | import org.junit.Test; 9 | 10 | /** 11 | * @author binbin.hou 12 | * @since 0.0.6 13 | */ 14 | public class NewInstanceTest { 15 | 16 | /** 17 | * 测试 18 | * @since 0.0.6 19 | */ 20 | @Test 21 | public void factoryMethodAnnotationTest() throws InterruptedException { 22 | BeanFactory beanFactory = new JsonApplicationContext("create/colorApple.json"); 23 | ColorApple apple = beanFactory.getBean("apple", ColorApple.class); 24 | System.out.println(apple); 25 | } 26 | 27 | /** 28 | * 构造器测试 29 | * @since 0.0.6 30 | */ 31 | @Test 32 | public void constructorTest() { 33 | BeanFactory beanFactory = new JsonApplicationContext("create/colorApple.json"); 34 | ColorWeightApple apple = beanFactory.getBean("weightApple", ColorWeightApple.class); 35 | System.out.println(apple); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/core/ParentTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.core; 2 | 3 | import com.github.houbb.ioc.context.JsonApplicationContext; 4 | import com.github.houbb.ioc.core.BeanFactory; 5 | import com.github.houbb.ioc.test.model.User; 6 | import com.github.houbb.ioc.test.service.Apple; 7 | import org.junit.Assert; 8 | import org.junit.Test; 9 | 10 | /** 11 | * 继承测试 12 | * @author binbin.hou 13 | * @since 0.0.9 14 | */ 15 | public class ParentTest { 16 | 17 | @Test 18 | public void parentNameTest() { 19 | final BeanFactory beanFactory = new JsonApplicationContext("parent/user-parent.json"); 20 | User copyUser = beanFactory.getBean("copyUser", User.class); 21 | Assert.assertEquals("helen", copyUser.getName()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/model/Book.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.model; 2 | 3 | /** 4 | * @author binbin.hou 5 | * @since 0.0.7 6 | */ 7 | public class Book { 8 | 9 | private String name; 10 | 11 | public Book() { 12 | } 13 | 14 | public Book(String name) { 15 | this.name = name; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "Book{" + 29 | "name='" + name + '\'' + 30 | '}'; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/model/User.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.model; 2 | 3 | /** 4 | * @author binbin.hou 5 | * @since 0.0.7 6 | */ 7 | public class User { 8 | 9 | private Book book; 10 | 11 | private String name; 12 | 13 | public Book getBook() { 14 | return book; 15 | } 16 | 17 | public void setBook(Book book) { 18 | this.book = book; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | return "User{" + 32 | "book=" + book + 33 | ", name='" + name + '\'' + 34 | '}'; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | *

project: ioc-package-info

3 | *

create on 2019/11/6 20:01

4 | * 5 | * @author Administrator 6 | * @since 1.0.0 7 | */ 8 | package com.github.houbb.ioc.test; -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/service/Apple.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.service; 2 | 3 | import javax.annotation.PostConstruct; 4 | import javax.annotation.PreDestroy; 5 | 6 | /** 7 | *

project: ioc-Apple

8 | *

create on 2019/11/6 20:02

9 | * 10 | * @author Administrator 11 | * @since 0.0.1 12 | */ 13 | public class Apple { 14 | 15 | @PostConstruct 16 | public void init() { 17 | System.out.println("Apple init"); 18 | } 19 | 20 | @PreDestroy 21 | public void destroy() { 22 | System.out.println("Apple destroy"); 23 | } 24 | 25 | public void color() { 26 | System.out.println("Apple color: red. "); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/service/ColorApple.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.service; 2 | 3 | import com.github.houbb.ioc.annotation.FactoryMethod; 4 | 5 | import javax.annotation.PostConstruct; 6 | import javax.annotation.PreDestroy; 7 | 8 | /** 9 | *

project: ioc-Apple

10 | *

create on 2019/11/6 20:02

11 | * 12 | * @author Administrator 13 | * @since 0.0.6 14 | */ 15 | public class ColorApple { 16 | 17 | /** 18 | * 颜色 19 | * @since 0.0.6 20 | */ 21 | private String color; 22 | 23 | /** 24 | * 自定义实例 25 | * @return 自定义结果 26 | * @since 0.0.6 27 | */ 28 | @FactoryMethod 29 | public static ColorApple newInstance() { 30 | ColorApple colorApple = new ColorApple(); 31 | colorApple.setColor("define"); 32 | return colorApple; 33 | } 34 | 35 | public String getColor() { 36 | return color; 37 | } 38 | 39 | public void setColor(String color) { 40 | this.color = color; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return "ColorApple{" + 46 | "color='" + color + '\'' + 47 | '}'; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/service/ColorWeightApple.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.service; 2 | 3 | /** 4 | *

project: ioc-Apple

5 | *

create on 2019/11/6 20:02

6 | * 7 | * @author Administrator 8 | * @since 0.0.6 9 | */ 10 | public class ColorWeightApple { 11 | 12 | /** 13 | * 重量 14 | * @since 0.0.6 15 | */ 16 | private Integer weight; 17 | 18 | /** 19 | * 颜色 20 | * @since 0.0.6 21 | */ 22 | private String color; 23 | 24 | /** 25 | * @since 0.1.0 26 | */ 27 | public ColorWeightApple() { 28 | } 29 | 30 | public ColorWeightApple(final ColorApple colorApple, Integer weight) { 31 | this.color = colorApple.getColor(); 32 | this.weight = weight; 33 | } 34 | 35 | public Integer getWeight() { 36 | return weight; 37 | } 38 | 39 | public void setWeight(Integer weight) { 40 | this.weight = weight; 41 | } 42 | 43 | public String getColor() { 44 | return color; 45 | } 46 | 47 | public void setColor(String color) { 48 | this.color = color; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "ColorWeightApple{" + 54 | "weight=" + weight + 55 | ", color='" + color + '\'' + 56 | '}'; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/service/WeightApple.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.service; 2 | 3 | /** 4 | *

project: ioc-Apple

5 | *

create on 2019/11/6 20:02

6 | * 7 | * @author Administrator 8 | * @since 0.1.2 9 | */ 10 | public class WeightApple { 11 | 12 | public void init() { 13 | System.out.println("WeightApple init"); 14 | } 15 | 16 | public void destroy() { 17 | System.out.println("WeightApple destroy"); 18 | } 19 | 20 | /** 21 | * 获取重量配置 22 | * @return 重量 23 | * @since 0.1.2 24 | */ 25 | public String getWeight() { 26 | return "10"; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/service/inner/QueryService.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.service.inner; 2 | 3 | import com.github.houbb.ioc.annotation.Service; 4 | 5 | /** 6 | *

project: ioc-QueryService

7 | *

create on 2019/12/1 14:25

8 | * 9 | * @author Administrator 10 | * @since 0.1.11 11 | */ 12 | @Service("myQueryService") 13 | public class QueryService { 14 | 15 | /** 16 | * 查询名称 17 | * @param id 唯一标识 18 | * @return 结果 19 | * @since 0.1.11 20 | */ 21 | public String queryName(final int id) { 22 | return id + "-name"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/service/inner/QueryServiceManager.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.service.inner; 2 | 3 | import com.github.houbb.ioc.annotation.Component; 4 | 5 | /** 6 | *

project: ioc-QueryService

7 | *

create on 2019/12/1 14:25

8 | * 9 | * @author Administrator 10 | * @since 0.1.11 11 | */ 12 | @Component 13 | public class QueryServiceManager { 14 | 15 | /** 16 | * 查询名称 17 | * @param id 唯一标识 18 | * @return 结果 19 | * @since 0.1.11 20 | */ 21 | public String queryName(final int id) { 22 | return id + "-manager"; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/support/condition/FalseCondition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.support.condition; 2 | 3 | import com.github.houbb.ioc.support.condition.Condition; 4 | import com.github.houbb.ioc.support.condition.ConditionContext; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | *

project: ioc-TrueCondition

10 | *

create on 2019/11/30 11:21

11 | * 12 | * @author Administrator 13 | * @since 0.1.8 14 | */ 15 | public class FalseCondition implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, Map attributes) { 18 | return false; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/support/condition/TrueCondition.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.support.condition; 2 | 3 | import com.github.houbb.ioc.support.condition.Condition; 4 | import com.github.houbb.ioc.support.condition.ConditionContext; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | *

project: ioc-TrueCondition

10 | *

create on 2019/11/30 11:21

11 | * 12 | * @author Administrator 13 | * @since 0.1.8 14 | */ 15 | public class TrueCondition implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, Map attributes) { 18 | return true; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/support/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | *

project: ioc-package-info

3 | *

create on 2019/11/30 11:21

4 | * 5 | * @author Administrator 6 | * @since 1.0.0 7 | */ 8 | package com.github.houbb.ioc.test.support; -------------------------------------------------------------------------------- /src/test/java/com/github/houbb/ioc/test/util/ClassUtilTest.java: -------------------------------------------------------------------------------- 1 | package com.github.houbb.ioc.test.util; 2 | 3 | import com.github.houbb.heaven.util.lang.reflect.ClassUtil; 4 | import com.github.houbb.ioc.support.envrionment.ConfigurableEnvironment; 5 | import com.github.houbb.ioc.support.envrionment.impl.DefaultEnvironment; 6 | import org.junit.Test; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | /** 12 | *

project: ioc-ClassUtilTest

13 | *

create on 2019/11/30 20:56

14 | * 15 | * @author Administrator 16 | * @since 0.1.10 17 | */ 18 | public class ClassUtilTest { 19 | 20 | @Test 21 | public void getParentClassTest() { 22 | List classList = ClassUtil.getAllInterfacesAndSuperClass(DefaultEnvironment.class); 23 | System.out.println(classList); 24 | System.out.println(Arrays.toString(ConfigurableEnvironment.class.getInterfaces())); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/test/resources/apple.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name":"apple","className":"com.github.houbb.ioc.test.service.Apple"} 3 | ] -------------------------------------------------------------------------------- /src/test/resources/apples.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name":"apple","className":"com.github.houbb.ioc.test.service.Apple"}, 3 | {"name":"apple2","className":"com.github.houbb.ioc.test.service.Apple"} 4 | ] -------------------------------------------------------------------------------- /src/test/resources/circle/direct-circle.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name":"weightApple","className":"com.github.houbb.ioc.test.service.ColorWeightApple","lazyInit":false,"constructorArgList":[{"ref":"weightApple2"},{"type":"java.lang.Integer","value":"10"}]}, 3 | {"name":"weightApple2","className":"com.github.houbb.ioc.test.service.ColorWeightApple","lazyInit":false,"constructorArgList":[{"ref":"weightApple"}]} 4 | ] -------------------------------------------------------------------------------- /src/test/resources/circle/in-direct-circle.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name":"weightApple","className":"com.github.houbb.ioc.test.service.ColorWeightApple","lazyInit":false,"constructorArgList":[{"ref":"weightApple2"},{"type":"java.lang.Integer","value":"10"}]}, 3 | {"name":"weightApple2","className":"com.github.houbb.ioc.test.service.ColorWeightApple","lazyInit":false,"constructorArgList":[{"ref":"weightApple3"}]}, 4 | {"name":"weightApple3","className":"com.github.houbb.ioc.test.service.ColorWeightApple","lazyInit":false,"constructorArgList":[{"ref":"weightApple"}]} 5 | ] -------------------------------------------------------------------------------- /src/test/resources/create/colorApple.json: -------------------------------------------------------------------------------- 1 | [{"name":"weightApple","className":"com.github.houbb.ioc.test.service.ColorWeightApple","lazyInit":false,"constructorArgList":[{"ref":"apple"},{"type":"java.lang.Integer","value":"10"}]},{"name":"apple","className":"com.github.houbb.ioc.test.service.ColorApple","lazyInit":false}] -------------------------------------------------------------------------------- /src/test/resources/name.properties: -------------------------------------------------------------------------------- 1 | name=hello -------------------------------------------------------------------------------- /src/test/resources/parent/user-parent.json: -------------------------------------------------------------------------------- 1 | [{"name":"copyUser","className":"com.github.houbb.ioc.test.model.User","parentName":"user"}, 2 | {"name":"user","className":"com.github.houbb.ioc.test.model.User","lazyInit":false, 3 | "propertyArgList":[{"name":"name","type":"java.lang.String","value":"helen"}]}] -------------------------------------------------------------------------------- /src/test/resources/property/user-property.json: -------------------------------------------------------------------------------- 1 | [{"name":"book","className":"com.github.houbb.ioc.test.model.Book","lazyInit":false},{"name":"user","className":"com.github.houbb.ioc.test.model.User","lazyInit":false,"propertyArgList":[{"name":"name","type":"java.lang.String","value":"helen"},{"name":"book","ref":"book"}]}] -------------------------------------------------------------------------------- /src/test/resources/singleton/apple-prototype.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name":"apple","className":"com.github.houbb.ioc.test.service.Apple","scope":"prototype", "lazyInit":false} 3 | ] -------------------------------------------------------------------------------- /src/test/resources/singleton/apple-singleton.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"name":"apple","className":"com.github.houbb.ioc.test.service.Apple","scope":"singleton", "lazyInit":false} 3 | ] --------------------------------------------------------------------------------