你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
如何自己实现一个简单的 Java IOC(Inversion of Control)容器,可以通过以下步骤来完成:
Bean 定义和管理:使用注解或 XML 定义 Bean。
依赖注入:支持构造函数注入和属性注入。
Bean 的生命周期管理:支持单例模式的 Bean。
定义注解用于标记组件和注入点。
// 标记为组件
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
// 标记为自动注入
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {}
实现一个核心容器来扫描和管理 Bean。
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class SimpleIOC {
private Map<String, Object> beanContainer = new HashMap<>();
public SimpleIOC(String packageName) throws Exception {
// 扫描包路径并初始化 Bean
scanPackage(packageName);
}
private void scanPackage(String packageName) throws Exception {
// 使用类加载器获取包路径下的所有类(这里可以用 ClassLoader 或第三方库)
// 为简化,假设扫描到了两个类:UserService 和 UserRepository
// 示例:手动注册 Bean(模拟扫描)
Class<?> userServiceClass = UserService.class;
Class<?> userRepositoryClass = UserRepository.class;
// 创建 Bean 并加入容器
registerBean(userServiceClass);
registerBean(userRepositoryClass);
// 依赖注入
autowireDependencies();
}
private void registerBean(Class<?> clazz) throws Exception {
if (clazz.isAnnotationPresent(Component.class)) {
Component component = clazz.getAnnotation(Component.class);
String beanName = component.value();
if (beanName.isEmpty()) {
beanName = clazz.getSimpleName();
}
Object instance = clazz.getDeclaredConstructor().newInstance();
beanContainer.put(beanName, instance);
}
}
private void autowireDependencies() throws Exception {
for (Object bean : beanContainer.values()) {
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class)) {
// 找到需要注入的类型
Class<?> fieldType = field.getType();
Object dependency = findBeanByType(fieldType);
if (dependency == null) {
throw new Exception("No bean found for type: " + fieldType.getName());
}
// 注入依赖
field.setAccessible(true);
field.set(bean, dependency);
}
}
}
}
private Object findBeanByType(Class<?> type) {
for (Object bean : beanContainer.values()) {
if (type.isAssignableFrom(bean.getClass())) {
return bean;
}
}
return null;
}
public Object getBean(String name) {
return beanContainer.get(name);
}
}
模拟服务和存储层。
@Component("userService")
public class UserService {
@Autowired
private UserRepository userRepository;
public void printUser() {
System.out.println("User: " + userRepository.getUser());
}
}
@Component("userRepository")
public class UserRepository {
public String getUser() {
return "John Doe";
}
}
测试 IOC 容器的初始化和使用。
public class Main {
public static void main(String[] args) throws Exception {
// 初始化 IOC 容器
SimpleIOC ioc = new SimpleIOC("com.example");
// 获取 Bean
UserService userService = (UserService) ioc.getBean("userService");
// 调用方法
userService.printUser(); // 输出: User: John Doe
}
}
@Component:标记一个类为 Bean。
@Autowired:支持字段的自动注入。
容器实现:
Bean 注册:扫描标记为 @Component 的类。
依赖注入:通过反射为 @Autowired 标记的字段注入依赖。
扫描类:可以用 ClassLoader 动态扫描包路径。
注入方式:支持构造器注入和方法注入。
Bean 生命周期:实现单例、多例模式支持。
扩展支持:添加 AOP、事件机制等。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!