implement lightweight IOC/DI framework
- Add annotation system (@Component, @Service, @Configuration, @Bean, @Inject, @Qualifier, @Primary, @Scope, @PostConstruct, @Import, @TimiInjectApplication) - Implement BeanContext for managing bean instances and definitions - Implement BeanScanner for component scanning (file system and jar) - Implement BeanFactory with constructor injection and lifecycle support - Support @Configuration and @Bean factory methods - Support @Qualifier and @Primary for multi-implementation - Support @Scope (singleton/prototype) - Support @PostConstruct lifecycle callback - Support @Import and Module extension - Add circular dependency detection - Add dependency graph export - Add demo and test cases Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
17
src/test/java/com/imyeyu/inject/demo/DefaultStorage.java
Normal file
17
src/test/java/com/imyeyu/inject/demo/DefaultStorage.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
import com.imyeyu.inject.annotation.Component;
|
||||
|
||||
/**
|
||||
* 默认存储实现
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Component
|
||||
public class DefaultStorage implements Storage {
|
||||
|
||||
@Override
|
||||
public void save(String data) {
|
||||
System.out.println("Default save: " + data);
|
||||
}
|
||||
}
|
||||
29
src/test/java/com/imyeyu/inject/demo/DemoApp.java
Normal file
29
src/test/java/com/imyeyu/inject/demo/DemoApp.java
Normal file
@ -0,0 +1,29 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
import com.imyeyu.inject.TimiInject;
|
||||
import com.imyeyu.inject.annotation.TimiInjectApplication;
|
||||
|
||||
/**
|
||||
* 演示应用
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@TimiInjectApplication("com.imyeyu.inject.demo")
|
||||
public class DemoApp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
TimiInject inject = TimiInject.run(DemoApp.class);
|
||||
|
||||
UserService userService = inject.di(UserService.class);
|
||||
System.out.println(userService.hello());
|
||||
|
||||
String appName = inject.di("appName", String.class);
|
||||
System.out.println("App Name: " + appName);
|
||||
|
||||
Storage storage = inject.di(Storage.class);
|
||||
System.out.println("Storage: " + storage.getClass().getSimpleName());
|
||||
|
||||
System.out.println("\n=== Dependency Graph ===");
|
||||
System.out.println(inject.exportDependencyGraph());
|
||||
}
|
||||
}
|
||||
23
src/test/java/com/imyeyu/inject/demo/DemoConfig.java
Normal file
23
src/test/java/com/imyeyu/inject/demo/DemoConfig.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
import com.imyeyu.inject.annotation.Bean;
|
||||
import com.imyeyu.inject.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 演示配置
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Configuration
|
||||
public class DemoConfig {
|
||||
|
||||
@Bean("appName")
|
||||
public String appName() {
|
||||
return "timi-inject-demo";
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Integer serverPort() {
|
||||
return 8080;
|
||||
}
|
||||
}
|
||||
19
src/test/java/com/imyeyu/inject/demo/FastStorage.java
Normal file
19
src/test/java/com/imyeyu/inject/demo/FastStorage.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
import com.imyeyu.inject.annotation.Component;
|
||||
import com.imyeyu.inject.annotation.Primary;
|
||||
|
||||
/**
|
||||
* 快速存储实现
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Component
|
||||
@Primary
|
||||
public class FastStorage implements Storage {
|
||||
|
||||
@Override
|
||||
public void save(String data) {
|
||||
System.out.println("Fast save: " + data);
|
||||
}
|
||||
}
|
||||
67
src/test/java/com/imyeyu/inject/demo/QuickTest.java
Normal file
67
src/test/java/com/imyeyu/inject/demo/QuickTest.java
Normal file
@ -0,0 +1,67 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
import com.imyeyu.inject.TimiInject;
|
||||
import com.imyeyu.inject.annotation.Component;
|
||||
import com.imyeyu.inject.annotation.PostConstruct;
|
||||
import com.imyeyu.inject.annotation.Service;
|
||||
import com.imyeyu.inject.annotation.TimiInjectApplication;
|
||||
|
||||
/**
|
||||
* 快速测试
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
public class QuickTest {
|
||||
|
||||
@TimiInjectApplication("com.imyeyu.inject.demo")
|
||||
public static class TestApp {
|
||||
}
|
||||
|
||||
@Service
|
||||
public static class TestService {
|
||||
private boolean initialized = false;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.initialized = true;
|
||||
System.out.println("TestService initialized");
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return initialized;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("=== Timi-Inject Quick Test ===\n");
|
||||
|
||||
TimiInject inject = TimiInject.run(TestApp.class);
|
||||
|
||||
System.out.println("\n=== Test 1: Simple DI ===");
|
||||
UserRepository repo = inject.di(UserRepository.class);
|
||||
System.out.println("UserRepository: " + (repo != null ? "OK" : "FAIL"));
|
||||
|
||||
System.out.println("\n=== Test 2: Constructor Injection ===");
|
||||
UserService service = inject.di(UserService.class);
|
||||
System.out.println("UserService: " + service.hello());
|
||||
|
||||
System.out.println("\n=== Test 3: @Bean Method ===");
|
||||
String appName = inject.di("appName", String.class);
|
||||
System.out.println("AppName: " + appName);
|
||||
|
||||
Integer port = inject.di("serverPort", Integer.class);
|
||||
System.out.println("ServerPort: " + port);
|
||||
|
||||
System.out.println("\n=== Test 4: @Primary ===");
|
||||
Storage storage = inject.di(Storage.class);
|
||||
System.out.println("Storage type: " + storage.getClass().getSimpleName());
|
||||
System.out.println("Expected FastStorage: " + (storage instanceof FastStorage ? "OK" : "FAIL"));
|
||||
|
||||
System.out.println("\n=== Test 5: Manual Registration ===");
|
||||
inject.ioc("customBean", "Custom Value");
|
||||
String custom = inject.di("customBean", String.class);
|
||||
System.out.println("Custom bean: " + custom);
|
||||
|
||||
System.out.println("\n=== All Tests Passed! ===");
|
||||
}
|
||||
}
|
||||
10
src/test/java/com/imyeyu/inject/demo/Storage.java
Normal file
10
src/test/java/com/imyeyu/inject/demo/Storage.java
Normal file
@ -0,0 +1,10 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
/**
|
||||
* 存储接口
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
public interface Storage {
|
||||
void save(String data);
|
||||
}
|
||||
16
src/test/java/com/imyeyu/inject/demo/UserRepository.java
Normal file
16
src/test/java/com/imyeyu/inject/demo/UserRepository.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
import com.imyeyu.inject.annotation.Resources;
|
||||
|
||||
/**
|
||||
* 用户仓储
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Resources
|
||||
public class UserRepository {
|
||||
|
||||
public UserRepository() {
|
||||
System.out.println("UserRepository created");
|
||||
}
|
||||
}
|
||||
28
src/test/java/com/imyeyu/inject/demo/UserService.java
Normal file
28
src/test/java/com/imyeyu/inject/demo/UserService.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.imyeyu.inject.demo;
|
||||
|
||||
import com.imyeyu.inject.annotation.PostConstruct;
|
||||
import com.imyeyu.inject.annotation.Service;
|
||||
|
||||
/**
|
||||
* 用户服务
|
||||
*
|
||||
* @author 夜雨
|
||||
*/
|
||||
@Service
|
||||
public class UserService {
|
||||
|
||||
private final UserRepository repository;
|
||||
|
||||
public UserService(UserRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
System.out.println("UserService initialized");
|
||||
}
|
||||
|
||||
public String hello() {
|
||||
return "Hello from UserService! Repository: " + repository.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user