如何编写自己的Spring容器
要编写自己的Spring容器,需实现核心功能:Bean定义、依赖注入、生命周期管理。以下是一个简化版的实现指南:
一、核心组件设计
1. BeanDefinition(Bean元数据)
public class BeanDefinition {private Class<?> beanClass;private String beanName;private Map<String, Object> properties = new HashMap<>();private String initMethodName;private String destroyMethodName;// Getters & Setters
}
2. Bean注册表(线程安全)
public class BeanRegistry {private final Map<String, BeanDefinition> beanDefinitions = new ConcurrentHashMap<>();private final Map<String, Object> singletonBeans = new ConcurrentHashMap<>();public void registerBeanDefinition(String beanName, BeanDefinition bd) {beanDefinitions.put(beanName, bd);}public BeanDefinition getBeanDefinition(String beanName) {return beanDefinitions.get(beanName);}
}
3. 容器核心接口
public interface BeanFactory {Object getBean(String name) throws Exception;
}
二、容器启动流程
1. 配置加载(示例:注解扫描)
public class AnnotationConfigApplicationContext extends BeanRegistry implements BeanFactory {public AnnotationConfigApplicationContext(Class<?> configClass) {scanComponents(configClass.getPackage().getName());refresh();}private void scanComponents(String packageName) {// 使用反射扫描指定包下的@Component注解类// 示例代码(需完善包扫描逻辑):Set<Class<?>> classes = ClassPathScanning.getClasses(packageName);for (Class<?> clazz : classes) {if (clazz.isAnnotationPresent(Component.class)) {Component component = clazz.getAnnotation(Component.class);String beanName = component.value().isEmpty() ? clazz.getSimpleName().toLowerCase() : component.value();registerBeanDefinition(beanName, createBeanDefinition(clazz));}}}
}
2. BeanDefinition解析
private BeanDefinition createBeanDefinition(Class<?> clazz) {BeanDefinition bd = new BeanDefinition();bd.setBeanClass(clazz);bd.setBeanName(clazz.getSimpleName().toLowerCase());// 解析字段上的@Autowired注解for (Field field : clazz.getDeclaredFields()) {if (field.isAnnotationPresent(Autowired.class)) {bd.getProperties().put(field.getName(), field.getType().getName());}}return bd;
}
3. 实例化与依赖注入
public Object getBean(String name) throws Exception {if (singletonBeans.containsKey(name)) {return singletonBeans.get(name);}BeanDefinition bd = getBeanDefinition(name);Object instance = bd.getBeanClass().newInstance();// 依赖注入for (Field field : bd.getBeanClass().getDeclaredFields()) {if (bd.getProperties().containsKey(field.getName())) {String dependencyName = bd.getProperties().get(field.getName());Object dependency = getBean(dependencyName);field.setAccessible(true);field.set(instance, dependency);}}// 初始化回调if (bd.getInitMethodName() != null) {Method initMethod = bd.getBeanClass().getMethod(bd.getInitMethodName());initMethod.invoke(instance);}singletonBeans.put(name, instance);return instance;
}
三、生命周期管理
1. Aware接口回调
// 在getBean中添加以下逻辑
if (instance instanceof BeanNameAware) {((BeanNameAware) instance).setBeanName(name);
}
if (instance instanceof BeanFactoryAware) {((BeanFactoryAware) instance).setBeanFactory(this);
}
2. 初始化阶段
// 在getBean中调用BeanPostProcessor(需实现扩展点)
for (BeanPostProcessor processor : beanPostProcessors) {instance = processor.postProcessBeforeInitialization(instance, name);
}// 执行初始化方法
if (bd.getInitMethodName() != null) {Method initMethod = bd.getBeanClass().getMethod(bd.getInitMethodName());initMethod.invoke(instance);
}for (BeanPostProcessor processor : beanPostProcessors) {instance = processor.postProcessAfterInitialization(instance, name);
}
3. 销毁阶段
public void close() {for (String beanName : singletonBeans.keySet()) {BeanDefinition bd = getBeanDefinition(beanName);Object bean = singletonBeans.get(beanName);if (bean instanceof DisposableBean) {((DisposableBean) bean).destroy();}if (bd.getDestroyMethodName() != null) {Method destroyMethod = bd.getBeanClass().getMethod(bd.getDestroyMethodName());destroyMethod.invoke(bean);}}
}
四、依赖注入实现
1. 反射工具类
public class ReflectionUtils {public static void setField(Object target, String fieldName, Object value) {Field field = target.getClass().getDeclaredField(fieldName);field.setAccessible(true);try {field.set(target, value);} catch (Exception e) {throw new RuntimeException("Failed to set field: " + fieldName, e);}}
}
2. 注解定义
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {String value() default "";
}@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {}
五、使用示例
1. 定义Bean
@Component
public class UserService {@Autowiredprivate UserRepository userRepository;public void init() {System.out.println("UserService initialized");}
}@Component
public class UserRepository {// ...
}
2. 启动容器
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
六、扩展功能
- BeanPostProcessor:实现自定义Bean增强逻辑
- 作用域支持:在BeanDefinition中添加scope字段,实现原型模式
- 配置文件支持:解析XML或Properties文件生成BeanDefinition
- 事件发布:实现ApplicationEventPublisher接口
通过以上步骤,你可以构建一个基础版的Spring容器,涵盖核心的IoC和DI功能。实际生产环境中的Spring容器更为复杂,但此示例展示了其核心设计思想。