@Binds/@IntoMap/@ClassKey的使用

下面是一个完整的 Dagger 多绑定映射(@IntoMap)示例,展示从定义到使用的全过程:

@Binds注解

@Binds:这是 Dagger 中的一个注解,用于声明某个抽象方法的返回类型是接口或抽象类,而方法的参数是其具体实现类!!!

@IntoMap

@IntoMap :将EngineService放入一个Map,Provider>集合中

@ClassKey

@ClassKey(EngineService.class) :EngineService.class作为放入Map的键key

Provider

延迟初始化(Lazy Initialization):只有在调用 get() 时才创建实例。

多次获取新实例(每次 get() 返回一个新实例,除非依赖是 @Singleton)。

解决循环依赖(Circular Dependencies)问题。

1. 定义服务接口和实现

// 服务接口
public interface CarService {
    void start();
}

// 引擎服务实现
public class EngineService implements CarService {
    @Inject
    public EngineService() {}
    
    @Override
    public void start() {
        System.out.println("Engine started");
    }
}

// 空调服务实现
public class AirConditioningService implements CarService {
    @Inject
    public AirConditioningService() {}
    
    @Override
    public void start() {
        System.out.println("AC cooling started");
    }
}

2. 创建 Dagger 模块

import dagger.Binds;
import dagger.Module;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;

@Module
public abstract class CarServiceModule {
    
    // 将 EngineService 绑定到 Map
    @Binds :EngineServiceCarService的实现类
    @IntoMap :EngineService放入一个Map<Class<?>,Provider<CarService>>集合中
    @ClassKey(EngineService.class) :EngineService.class作为放入Map的键key
    abstract CarService bindEngineService(EngineService impl);
    
    // 将 AirConditioningService 绑定到 Map
    @Binds
    @IntoMap
    @ClassKey(AirConditioningService.class)
    abstract CarService bindAirConditioningService(AirConditioningService impl);
}

3. 创建服务管理器

import javax.inject.Inject;
import java.util.Map;

public class ServiceManager {
    private final Map<Class<?>,Provider<CarService>> serviceMap;
    
    @Inject
    public ServiceManager(Map<Class<?>,Provider<CarService>> serviceMap) {
        this.serviceMap = serviceMap;
        System.out.println("ServiceManager initialized with services: " + serviceMap.keySet());
    }
    
    public CarService getService(Class<?> serviceClass) {
        return serviceMap.get(serviceClass);
    }
}

4. 创建 Dagger 组件

import dagger.Component;

@Component(modules = CarServiceModule.class)
public interface CarComponent {
    ServiceManager getServiceManager();
    
    // 可选:直接获取Map
    Map<Class<?>,Provider<CarService>> getServiceMap();
}

5. 使用示例

public class CarApp {
    public static void main(String[] args) {
        // 创建Dagger组件
        CarComponent component = DaggerCarComponent.create();
        
        // 获取服务管理器
        ServiceManager manager = component.getServiceManager();
        
        // 使用服务
        CarService engine = manager.getService(EngineService.class);
        engine.start(); // 输出: Engine started
        
        CarService ac = manager.getService(AirConditioningService.class);
        ac.start(); // 输出: AC cooling started
        
        // 直接获取Map
        Map<Class<?>,Provider<CarService>> serviceMap = component.getServiceMap();
        System.out.println("Direct map access: " + serviceMap.keySet());
    }
}

6. 生成的 Dagger 代码 (简化版)

// DaggerCarComponent.java (自动生成)
public final class DaggerCarComponent implements CarComponent {
    private final Map<Class<?>, Provider<CarService>> serviceMapProvider;
    
    private DaggerCarComponent() {
        this.serviceMapProvider = createServiceMap();
    }
    
    private Map<Class<?>, Provider<CarService>> createServiceMap() {
        Map<Class<?>, Provider<CarService>> map = new HashMap<>();
        
        // 绑定EngineService
        Provider<EngineService> engineProvider = 
            DoubleCheck.provider(EngineService_Factory.create());
        map.put(EngineService.class, (Provider)engineProvider);
        
        // 绑定AirConditioningService
        Provider<AirConditioningService> acProvider = 
            DoubleCheck.provider(AirConditioningService_Factory.create());
        map.put(AirConditioningService.class, (Provider)acProvider);
        
        return Collections.unmodifiableMap(map);
    }
    
    @Override
    public ServiceManager getServiceManager() {
        return new ServiceManager(
            MapProviderFactory.<Class<?>, CarService>create(serviceMapProvider).get()
        );
    }
    
    @Override
    public Map<Class<?>,Provider<CarService>> getServiceMap() {
        return MapProviderFactory.<Class<?>, CarService>create(serviceMapProvider).get();
    }
}

输出结果

ServiceManager initialized with services: [class EngineService, class AirConditioningService]
Engine started
AC cooling started
Direct map access: {class EngineService=EngineService@1234, class AirConditioningService=AirConditioningService@5678}

你可能感兴趣的:(@Binds/@IntoMap/@ClassKey的使用)