你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
如何自己实现一个简单的 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 {// 扫描包路径并初始化 BeanscanPackage(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 {@Autowiredprivate 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");// 获取 BeanUserService userService = (UserService) ioc.getBean("userService");// 调用方法userService.printUser(); // 输出: User: John Doe}}
@Component:标记一个类为 Bean。
@Autowired:支持字段的自动注入。
容器实现:
Bean 注册:扫描标记为 @Component 的类。
依赖注入:通过反射为 @Autowired 标记的字段注入依赖。
扫描类:可以用 ClassLoader 动态扫描包路径。
注入方式:支持构造器注入和方法注入。
Bean 生命周期:实现单例、多例模式支持。
扩展支持:添加 AOP、事件机制等。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!