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<>();
// ...
}