Java实现IOC容器案例

wen java案例 3

本文目录导读:

Java实现IOC容器案例

  1. 核心注解定义
  2. 核心类定义
  3. IOC容器核心实现
  4. 自动装配处理器
  5. 测试使用示例
  6. 增强功能
  7. 使用示例(扫描方式)

我将为您创建一个完整的Java IOC容器实现案例,这个案例将展示如何从零开始构建一个轻量级的依赖注入容器。

核心注解定义

// Inject.java - 依赖注入注解
package com.example.ioc.annotation;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Inject {
}
// Component.java - 组件注解
package com.example.ioc.annotation;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {
    String name() default "";
}
// Configuration.java - 配置类注解
package com.example.ioc.annotation;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Configuration {
}
// Bean.java - Bean定义注解
package com.example.ioc.annotation;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
    String name() default "";
}

核心类定义

// BeanDefinition.java - Bean定义类
package com.example.ioc.core;
import java.lang.reflect.Method;
public class BeanDefinition {
    private String beanName;
    private Class<?> beanClass;
    private Object beanInstance;
    private boolean singleton = true;
    private Method factoryMethod;
    private String factoryBeanName;
    private String scope = "singleton";
    private boolean lazyInit = false;
    // 构造函数
    public BeanDefinition(Class<?> clazz) {
        this.beanClass = clazz;
        this.beanName = clazz.getSimpleName();
    }
    // Getters and Setters
    public String getBeanName() { return beanName; }
    public void setBeanName(String beanName) { this.beanName = beanName; }
    public Class<?> getBeanClass() { return beanClass; }
    public void setBeanClass(Class<?> beanClass) { this.beanClass = beanClass; }
    public Object getBeanInstance() { return beanInstance; }
    public void setBeanInstance(Object beanInstance) { this.beanInstance = beanInstance; }
    public boolean isSingleton() { return singleton; }
    public void setSingleton(boolean singleton) { this.singleton = singleton; }
    public Method getFactoryMethod() { return factoryMethod; }
    public void setFactoryMethod(Method factoryMethod) { this.factoryMethod = factoryMethod; }
    public String getFactoryBeanName() { return factoryBeanName; }
    public void setFactoryBeanName(String factoryBeanName) { this.factoryBeanName = factoryBeanName; }
    public String getScope() { return scope; }
    public void setScope(String scope) { this.scope = scope; }
    public boolean isLazyInit() { return lazyInit; }
    public void setLazyInit(boolean lazyInit) { this.lazyInit = lazyInit; }
}
// BeanPostProcessor.java - Bean后处理器接口
package com.example.ioc.core;
public interface BeanPostProcessor {
    default Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }
    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}
// BeanFactory.java - Bean工厂接口
package com.example.ioc.core;
public interface BeanFactory {
    Object getBean(String name);
    <T> T getBean(Class<T> clazz);
    boolean containsBean(String name);
    void registerBean(String name, Object bean);
    void registerBeanDefinition(BeanDefinition definition);
    void refresh();
}

IOC容器核心实现

// SimpleBeanFactory.java - Bean工厂实现
package com.example.ioc.core;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class SimpleBeanFactory implements BeanFactory {
    private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
    @Override
    public void registerBean(String name, Object bean) {
        beanDefinitionMap.put(name, new BeanDefinition(bean.getClass()));
        singletonObjects.put(name, bean);
    }
    @Override
    public void registerBeanDefinition(BeanDefinition definition) {
        beanDefinitionMap.put(definition.getBeanName(), definition);
    }
    @Override
    public void refresh() {
        // 注册后处理器
        registerBeanPostProcessors();
        // 非懒加载的bean实例化
        instantiateSingletons();
    }
    private void registerBeanPostProcessors() {
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            if (BeanPostProcessor.class.isAssignableFrom(entry.getValue().getBeanClass())) {
                beanPostProcessors.add((BeanPostProcessor) doCreateBean(entry.getValue()));
            }
        }
    }
    private void instantiateSingletons() {
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            BeanDefinition definition = entry.getValue();
            if (!definition.isLazyInit() && definition.isSingleton() && 
                !definition.getBeanClass().equals(BeanPostProcessor.class)) {
                doCreateBean(definition);
            }
        }
    }
    private Object doCreateBean(BeanDefinition definition) {
        Object bean = null;
        try {
            // 实例化bean
            if (definition.getFactoryMethod() != null) {
                bean = createByFactoryMethod(definition);
            } else {
                bean = createByConstructor(definition);
            }
            // 进行属性注入
            applyPropertyValues(definition, bean);
            // 处理Aware接口
            invokeAwareMethods(bean);
            // 后处理器
            bean = applyBeanPostProcessorsBeforeInitialization(bean, definition.getBeanName());
            // 初始化方法
            invokeInitMethod(bean);
            bean = applyBeanPostProcessorsAfterInitialization(bean, definition.getBeanName());
        } catch (Exception e) {
            throw new RuntimeException("创建Bean失败: " + definition.getBeanName(), e);
        }
        return bean;
    }
    private Object createByConstructor(BeanDefinition definition) throws Exception {
        Class<?> clazz = definition.getBeanClass();
        Object instance = clazz.getDeclaredConstructor().newInstance();
        if (definition.isSingleton()) {
            singletonObjects.put(definition.getBeanName(), instance);
        }
        return instance;
    }
    private Object createByFactoryMethod(BeanDefinition definition) throws Exception {
        Object factoryBean = getBean(definition.getFactoryBeanName());
        definition.getFactoryMethod().setAccessible(true);
        Object instance = definition.getFactoryMethod().invoke(factoryBean);
        if (definition.isSingleton()) {
            singletonObjects.put(definition.getBeanName(), instance);
        }
        return instance;
    }
    private void applyPropertyValues(BeanDefinition definition, Object bean) throws IllegalAccessException {
        // 使用ReflectionUtils进行属性注入
        // 这里简化处理,实际实现可以通过BeanPostProcessor和AutowiredAnnotationBeanPostProcessor
        for (java.lang.reflect.Field field : definition.getBeanClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(com.example.ioc.annotation.Inject.class)) {
                field.setAccessible(true);
                Object dependency = getBean(field.getType());
                field.set(bean, dependency);
            }
        }
    }
    private void invokeAwareMethods(Object bean) {
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(this);
        }
        if (bean instanceof BeanNameAware) {
            // 设置bean名称
        }
    }
    private Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
        Object result = existingBean;
        for (BeanPostProcessor processor : beanPostProcessors) {
            result = processor.postProcessBeforeInitialization(result, beanName);
        }
        return result;
    }
    private Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
        Object result = existingBean;
        for (BeanPostProcessor processor : beanPostProcessors) {
            result = processor.postProcessAfterInitialization(result, beanName);
        }
        return result;
    }
    private void invokeInitMethod(Object bean) {
        // 调用@PostConstruct初始化方法
    }
    @Override
    public Object getBean(String name) {
        BeanDefinition definition = beanDefinitionMap.get(name);
        if (definition == null) {
            throw new IllegalArgumentException("No bean named '" + name + "' is defined");
        }
        if (definition.isSingleton()) {
            Object bean = singletonObjects.get(name);
            if (bean == null) {
                bean = doCreateBean(definition);
            }
            return bean;
        } else {
            // prototype scope
            return doCreateBean(definition);
        }
    }
    @Override
    public <T> T getBean(Class<T> clazz) {
        for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
            if (clazz.isAssignableFrom(entry.getValue().getBeanClass())) {
                return (T) getBean(entry.getKey());
            }
        }
        throw new IllegalArgumentException("No bean found for type: " + clazz.getName());
    }
    @Override
    public boolean containsBean(String name) {
        return beanDefinitionMap.containsKey(name);
    }
}

自动装配处理器

// AutowiredAnnotationBeanPostProcessor.java
package com.example.ioc.processor;
import com.example.ioc.core.BeanFactory;
import com.example.ioc.core.BeanPostProcessor;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class AutowiredAnnotationBeanPostProcessor implements BeanPostProcessor {
    private BeanFactory beanFactory;
    private Map<String, Object> injectedBeans = new ConcurrentHashMap<>();
    public AutowiredAnnotationBeanPostProcessor(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 处理@Inject注解的属性注入
        injectFields(bean);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
    private void injectFields(Object bean) {
        Class<?> clazz = bean.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(com.example.ioc.annotation.Inject.class)) {
                field.setAccessible(true);
                try {
                    Object dependency = beanFactory.getBean(field.getType());
                    field.set(bean, dependency);
                    injectedBeans.put(bean.getClass().getName() + "#" + field.getName(), dependency);
                } catch (Exception e) {
                    throw new RuntimeException("注入失败: " + field.getName(), e);
                }
            }
        }
    }
}

测试使用示例

// 服务类定义
package com.example.demo.service;
import com.example.ioc.annotation.Component;
import com.example.ioc.annotation.Inject;
@Component("userService")
public class UserService {
    @Inject
    private UserRepository userRepository;
    @Inject
    private EmailService emailService;
    public void createUser(String username, String email) {
        User user = new User(username, email);
        userRepository.save(user);
        emailService.sendWelcomeEmail(email);
        System.out.println("用户创建成功: " + username);
    }
    public User getUser(String username) {
        return userRepository.findByUsername(username);
    }
}
// 仓库类
package com.example.demo.repository;
import com.example.ioc.annotation.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component("userRepository")
public class UserRepository {
    private Map<String, User> userDatabase = new ConcurrentHashMap<>();
    public void save(User user) {
        userDatabase.put(user.getUsername(), user);
    }
    public User findByUsername(String username) {
        return userDatabase.get(username);
    }
}
// 邮件服务
package com.example.demo.service;
import com.example.ioc.annotation.Component;
import com.example.ioc.annotation.Inject;
@Component
public class EmailService {
    public void sendWelcomeEmail(String email) {
        System.out.println("发送欢迎邮件到: " + email);
    }
    public void sendNotification(String email, String message) {
        System.out.println("发送通知到 " + email + ": " + message);
    }
}
// 用户实体
package com.example.demo.model;
public class User {
    private String username;
    private String email;
    public User(String username, String email) {
        this.username = username;
        this.email = email;
    }
    // Getters and Setters
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}
// 配置类
package com.example.demo.config;
import com.example.ioc.annotation.Bean;
import com.example.ioc.annotation.Configuration;
import com.example.demo.service.EmailService;
@Configuration
public class AppConfig {
    @Bean
    public EmailService emailService() {
        EmailService emailService = new EmailService();
        // 进行一些初始化配置
        return emailService;
    }
}
// 主程序测试类
package com.example.demo;
import com.example.ioc.core.SimpleBeanFactory;
import com.example.demo.service.UserService;
import com.example.demo.repository.UserRepository;
import com.example.demo.model.User;
public class Main {
    public static void main(String[] args) {
        // 创建IOC容器
        SimpleBeanFactory beanFactory = new SimpleBeanFactory();
        // 注册Bean定义
        beanFactory.registerBeanDefinition(new BeanDefinition(UserService.class));
        beanFactory.registerBeanDefinition(new BeanDefinition(UserRepository.class));
        beanFactory.registerBeanDefinition(new BeanDefinition(EmailService.class));
        // 刷新容器(初始化所有bean)
        beanFactory.refresh();
        // 从容器获取bean并使用
        UserService userService = beanFactory.getBean(UserService.class);
        // 测试功能
        System.out.println("=== 测试IOC容器 ===");
        userService.createUser("张三", "zhangsan@example.com");
        // 验证用户已创建
        User user = userService.getUser("张三");
        System.out.println("查询用户: " + user.getUsername() + " - " + user.getEmail());
        System.out.println("\n=== 测试结束 ===");
    }
}

增强功能

// ApplicationContext.java - 应用上下文接口
package com.example.ioc.context;
import com.example.ioc.core.BeanFactory;
public interface ApplicationContext extends BeanFactory {
    void close();
    String getApplicationName();
    long getStartupDate();
}
// AnnotationConfigApplicationContext.java
package com.example.ioc.context;
import com.example.ioc.annotation.Component;
import com.example.ioc.core.BeanDefinition;
import com.example.ioc.core.SimpleBeanFactory;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class AnnotationConfigApplicationContext implements ApplicationContext {
    private SimpleBeanFactory beanFactory;
    private String basePackage;
    private long startupDate;
    public AnnotationConfigApplicationContext(String basePackage) {
        this.basePackage = basePackage;
        this.startupDate = System.currentTimeMillis();
        this.beanFactory = new SimpleBeanFactory();
        // 扫描并注册所有Bean
        scanAndRegisterBeans();
        beanFactory.refresh();
    }
    private void scanAndRegisterBeans() {
        List<Class<?>> classes = scanPackage(basePackage);
        for (Class<?> clazz : classes) {
            if (clazz.isAnnotationPresent(Component.class)) {
                Component component = clazz.getAnnotation(Component.class);
                String beanName = component.name().isEmpty() ? clazz.getSimpleName() : component.name();
                BeanDefinition definition = new BeanDefinition(clazz);
                definition.setBeanName(beanName);
                beanFactory.registerBeanDefinition(definition);
            }
        }
    }
    private List<Class<?>> scanPackage(String packageName) {
        List<Class<?>> classes = new ArrayList<>();
        String path = packageName.replace('.', '/');
        URL resource = getClass().getClassLoader().getResource(path);
        File directory = new File(resource.getFile());
        for (File file : directory.listFiles()) {
            if (file.getName().endsWith(".class")) {
                String className = packageName + "." + 
                    file.getName().substring(0, file.getName().length() - 6);
                try {
                    classes.add(Class.forName(className));
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            } else if (file.isDirectory()) {
                classes.addAll(scanPackage(packageName + "." + file.getName()));
            }
        }
        return classes;
    }
    @Override
    public void close() {
        // 清理资源
        beanFactory = null;
    }
    @Override
    public String getApplicationName() {
        return basePackage;
    }
    @Override
    public long getStartupDate() {
        return startupDate;
    }
    @Override
    public Object getBean(String name) {
        return beanFactory.getBean(name);
    }
    @Override
    public <T> T getBean(Class<T> clazz) {
        return beanFactory.getBean(clazz);
    }
    @Override
    public boolean containsBean(String name) {
        return beanFactory.containsBean(name);
    }
    @Override
    public void registerBean(String name, Object bean) {
        beanFactory.registerBean(name, bean);
    }
    @Override
    public void registerBeanDefinition(BeanDefinition definition) {
        beanFactory.registerBeanDefinition(definition);
    }
    @Override
    public void refresh() {
        beanFactory.refresh();
    }
}

使用示例(扫描方式)

// 使用扫描方式启动容器
public class Application {
    public static void main(String[] args) {
        // 通过扫描包方式创建容器
        AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext("com.example.demo");
        // 获取bean
        UserService userService = context.getBean(UserService.class);
        // 测试功能
        userService.createUser("李四", "lisi@example.com");
        // 关闭容器
        context.close();
    }
}

这个IOC容器实现了以下核心功能:

  1. 依赖注入:通过@Inject注解注入依赖
  2. Bean生命周期管理:创建、初始化、销毁
  3. 作用域支持:singleton和prototype
  4. 后处理器机制:BeanPostProcessor
  5. 自动扫描:包扫描自动注册Bean
  6. 配置文件支持:通过@Configuration和@Bean定义Bean

这个案例展示了Spring IOC容器的核心原理,可以作为学习依赖注入和IOC设计模式的参考。

抱歉,评论功能暂时关闭!