Skip to content

IoC/DI 容器

LCGYL Framework 提供了轻量级的 IoC(控制反转)和 DI(依赖注入)容器。

核心概念

控制反转(IoC)

将对象的创建和管理权交给容器,而不是由程序员手动创建。

依赖注入(DI)

容器自动将依赖的对象注入到需要的地方。

组件注册

使用 @Component 注解

java
import com.lcgyl.framework.core.annotation.Component;

@Component
public class UserService {
    public void createUser(String name) {
        System.out.println("创建用户: " + name);
    }
}

指定作用域

java
import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.framework.core.annotation.Scope;

@Component
@Scope("prototype") // 每次获取都创建新实例
public class RequestHandler {
    // ...
}

支持的作用域:

  • singleton(默认)- 单例模式
  • prototype - 原型模式,每次创建新实例

依赖注入

字段注入

java
import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.framework.core.annotation.Inject;

@Component
public class UserController {
    
    @Inject
    private UserService userService;
    
    public void handleCreateUser(String name) {
        userService.createUser(name);
    }
}

构造器注入(推荐)

java
@Component
public class UserController {
    
    private final UserService userService;
    private final Logger logger;
    
    @Inject
    public UserController(UserService userService, Logger logger) {
        this.userService = userService;
        this.logger = logger;
    }
}

Setter 注入

java
@Component
public class UserController {
    
    private UserService userService;
    
    @Inject
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

容器使用

创建容器

java
import com.lcgyl.framework.core.Container;

public class Application {
    public static void main(String[] args) {
        // 创建容器
        Container container = new Container();
        
        // 扫描组件
        container.scan("com.example");
        
        // 获取 Bean
        UserService userService = container.getBean(UserService.class);
        userService.createUser("张三");
    }
}

手动注册 Bean

java
// 注册单例
container.registerSingleton(UserService.class, new UserService());

// 注册工厂方法
container.registerFactory(UserService.class, () -> {
    UserService service = new UserService();
    service.init();
    return service;
});

获取 Bean

java
// 按类型获取
UserService service = container.getBean(UserService.class);

// 按名称获取
UserService service = container.getBean("userService", UserService.class);

// 获取所有实现
List<MessageHandler> handlers = container.getBeans(MessageHandler.class);

生命周期回调

初始化回调

java
import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.framework.core.annotation.PostConstruct;

@Component
public class DatabaseService {
    
    private Connection connection;
    
    @PostConstruct
    public void init() {
        // Bean 创建后自动调用
        this.connection = createConnection();
        System.out.println("数据库连接已建立");
    }
}

销毁回调

java
import com.lcgyl.framework.core.annotation.PreDestroy;

@Component
public class DatabaseService {
    
    private Connection connection;
    
    @PreDestroy
    public void cleanup() {
        // 容器关闭前自动调用
        if (connection != null) {
            connection.close();
            System.out.println("数据库连接已关闭");
        }
    }
}

条件注册

基于配置的条件注册

java
import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.framework.core.annotation.ConditionalOnProperty;

@Component
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public class CacheService {
    // 只有当 cache.enabled=true 时才注册
}

基于类存在的条件注册

java
@Component
@ConditionalOnClass("com.example.AdvancedFeature")
public class AdvancedService {
    // 只有当 AdvancedFeature 类存在时才注册
}

完整示例

定义接口

java
public interface MessageService {
    void sendMessage(String message);
}

实现类

java
@Component
public class EmailService implements MessageService {
    
    @Override
    public void sendMessage(String message) {
        System.out.println("发送邮件: " + message);
    }
}

@Component
public class SmsService implements MessageService {
    
    @Override
    public void sendMessage(String message) {
        System.out.println("发送短信: " + message);
    }
}

使用服务

java
@Component
public class NotificationService {
    
    private final List<MessageService> messageServices;
    
    @Inject
    public NotificationService(List<MessageService> messageServices) {
        this.messageServices = messageServices;
    }
    
    public void notifyAll(String message) {
        // 自动注入所有 MessageService 实现
        messageServices.forEach(service -> service.sendMessage(message));
    }
}

运行应用

java
public class Application {
    public static void main(String[] args) {
        Container container = new Container();
        container.scan("com.example");
        
        NotificationService notificationService = 
            container.getBean(NotificationService.class);
        
        notificationService.notifyAll("系统维护通知");
        
        // 输出:
        // 发送邮件: 系统维护通知
        // 发送短信: 系统维护通知
    }
}

最佳实践

1. 优先使用构造器注入

java
// ✅ 推荐
@Component
public class UserService {
    private final UserRepository repository;
    
    @Inject
    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

// ❌ 不推荐
@Component
public class UserService {
    @Inject
    private UserRepository repository;
}

2. 避免循环依赖

java
// ❌ 避免
@Component
public class ServiceA {
    @Inject
    private ServiceB serviceB;
}

@Component
public class ServiceB {
    @Inject
    private ServiceA serviceA; // 循环依赖!
}

3. 使用接口编程

java
// ✅ 推荐
@Component
public class UserController {
    private final UserService userService;
    
    @Inject
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

4. 合理使用作用域

java
// 无状态服务使用单例
@Component
@Scope("singleton")
public class CalculatorService {
    // ...
}

// 有状态对象使用原型
@Component
@Scope("prototype")
public class ShoppingCart {
    private List<Item> items = new ArrayList<>();
    // ...
}

下一步

Released under the Apache License 2.0