本文目录导读:

我将为您创建一个完整的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容器实现了以下核心功能:
- 依赖注入:通过@Inject注解注入依赖
- Bean生命周期管理:创建、初始化、销毁
- 作用域支持:singleton和prototype
- 后处理器机制:BeanPostProcessor
- 自动扫描:包扫描自动注册Bean
- 配置文件支持:通过@Configuration和@Bean定义Bean
这个案例展示了Spring IOC容器的核心原理,可以作为学习依赖注入和IOC设计模式的参考。