本文目录导读:

- 基础配置实体类
- 核心配置管理器
- 配置源接口和实现
- 配置缓存实现
- 使用示例
- 高级应用:注解驱动的配置绑定
- 配置文件示例 (
application.properties) - Maven依赖 (
pom.xml) - 关键特性说明
我来为您提供一个完整的Java配置管理案例,包含多种常见场景和最佳实践。
基础配置实体类
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Properties;
import java.io.InputStream;
import java.io.IOException;
/**
* 配置项实体类
*/
public class ConfigItem {
private String key;
private String value;
private String description;
private String group;
private boolean isSensitive;
private String dataType; // string, int, boolean, double, json
public ConfigItem() {}
public ConfigItem(String key, String value, String description,
String group, boolean isSensitive, String dataType) {
this.key = key;
this.value = value;
this.description = description;
this.group = group;
this.isSensitive = isSensitive;
this.dataType = dataType;
}
// Getters and Setters
public String getKey() { return key; }
public void setKey(String key) { this.key = key; }
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
public String getGroup() { return group; }
public void setGroup(String group) { this.group = group; }
public boolean isSensitive() { return isSensitive; }
public void setSensitive(boolean sensitive) { isSensitive = sensitive; }
public String getDataType() { return dataType; }
public void setDataType(String dataType) { this.dataType = dataType; }
}
核心配置管理器
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
/**
* 配置管理器 - 支持热更新、监听、缓存
*/
public class ConfigManager {
private static volatile ConfigManager instance;
// 配置存储
private final Map<String, ConfigItem> configs = new ConcurrentHashMap<>();
// 配置变更监听器
private final Map<String, List<Consumer<ConfigItem>>> listeners = new ConcurrentHashMap<>();
// 全局监听器
private final List<Consumer<String>> globalListeners = new ArrayList<>();
// 配置来源
private ConfigSource source;
// 缓存管理
private final ConfigCache cache;
// 刷新锁
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
// 初始化状态
private final AtomicBoolean initialized = new AtomicBoolean(false);
// 定期刷新调度器
private ScheduledExecutorService scheduler;
private ScheduledFuture<?> refreshTask;
private ConfigManager() {
this.cache = new ConfigCache(1000); // 默认缓存1秒
initScheduler();
}
public static ConfigManager getInstance() {
if (instance == null) {
synchronized (ConfigManager.class) {
if (instance == null) {
instance = new ConfigManager();
}
}
}
return instance;
}
/**
* 初始化配置源
*/
public void init(ConfigSource source) {
this.source = source;
loadAllConfigs();
initialized.set(true);
}
/**
* 加载所有配置
*/
private void loadAllConfigs() {
if (source == null) return;
lock.writeLock().lock();
try {
Map<String, ConfigItem> loadedConfigs = source.loadAllConfigs();
if (loadedConfigs != null) {
// 对比旧配置,找出变化
detectChanges(configs, loadedConfigs);
configs.clear();
configs.putAll(loadedConfigs);
}
} finally {
lock.writeLock().unlock();
}
}
/**
* 检测配置变更并通知
*/
private void detectChanges(Map<String, ConfigItem> oldConfigs,
Map<String, ConfigItem> newConfigs) {
if (oldConfigs.isEmpty()) return;
// 检查更新和删除
for (Map.Entry<String, ConfigItem> entry : oldConfigs.entrySet()) {
String key = entry.getKey();
ConfigItem newItem = newConfigs.get(key);
if (newItem == null) {
// 配置被删除
notifyListeners(key, null);
} else if (!Objects.equals(entry.getValue().getValue(), newItem.getValue())) {
// 配置值变更
notifyListeners(key, newItem);
}
}
// 检查新增
for (String key : newConfigs.keySet()) {
if (!oldConfigs.containsKey(key)) {
notifyListeners(key, newConfigs.get(key));
}
}
}
/**
* 获取配置(带缓存)
*/
public String getConfig(String key) {
return getConfig(key, null);
}
/**
* 获取配置(带默认值)
*/
public String getConfig(String key, String defaultValue) {
lock.readLock().lock();
try {
// 尝试从缓存获取
Object cached = cache.get(key);
if (cached != null) {
return (String) cached;
}
// 从配置存储获取
ConfigItem item = configs.get(key);
String value = item != null ? item.getValue() : defaultValue;
// 缓存结果
cache.put(key, value);
return value;
} finally {
lock.readLock().unlock();
}
}
/**
* 获取带类型的配置
*/
public int getInt(String key, int defaultValue) {
String value = getConfig(key);
if (value == null) return defaultValue;
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
public boolean getBoolean(String key, boolean defaultValue) {
String value = getConfig(key);
if (value == null) return defaultValue;
return Boolean.parseBoolean(value);
}
public double getDouble(String key, double defaultValue) {
String value = getConfig(key);
if (value == null) return defaultValue;
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
return defaultValue;
}
}
/**
* 设置配置(并通知变更)
*/
public void setConfig(String key, String value) {
setConfig(key, value, true);
}
/**
* 设置配置
*/
public void setConfig(String key, String value, boolean notifyChange) {
lock.writeLock().lock();
try {
ConfigItem oldItem = configs.get(key);
if (oldItem == null) {
// 新增配置
ConfigItem newItem = new ConfigItem(key, value, "", "default", false, "string");
configs.put(key, newItem);
if (notifyChange) {
notifyListeners(key, newItem);
}
} else {
// 更新配置
oldItem.setValue(value);
oldItem.setDataType(detectDataType(value));
// 更新到配置源
if (source != null) {
source.updateConfig(key, value);
}
if (notifyChange) {
notifyListeners(key, oldItem);
}
}
// 更新缓存
cache.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
/**
* 批量设置配置
*/
public void setConfigs(Map<String, String> configMap) {
lock.writeLock().lock();
try {
for (Map.Entry<String, String> entry : configMap.entrySet()) {
setConfig(entry.getKey(), entry.getValue(), false);
}
// 触发全局变更通知
notifyGlobalListeners("batch_update");
} finally {
lock.writeLock().unlock();
}
}
/**
* 注册配置监听器
*/
public void registerListener(String key, Consumer<ConfigItem> listener) {
listeners.computeIfAbsent(key, k -> new CopyOnWriteArrayList<>())
.add(listener);
}
/**
* 注册全局监听器
*/
public void registerGlobalListener(Consumer<String> listener) {
globalListeners.add(listener);
}
/**
* 通知指定配置的监听器
*/
private void notifyListeners(String key, ConfigItem item) {
// 通知指定key的监听器
List<Consumer<ConfigItem>> keyListeners = listeners.get(key);
if (keyListeners != null) {
for (Consumer<ConfigItem> listener : keyListeners) {
try {
listener.accept(item);
} catch (Exception e) {
// 异常处理
}
}
}
// 通知全局监听器
notifyGlobalListeners(key);
}
/**
* 通知全局监听器
*/
private void notifyGlobalListeners(String key) {
for (Consumer<String> listener : globalListeners) {
try {
listener.accept(key);
} catch (Exception e) {
// 异常处理
}
}
}
/**
* 刷新配置
*/
public void refresh() {
if (source != null) {
loadAllConfigs();
}
}
/**
* 定时刷新
*/
public void scheduleRefresh(long interval, TimeUnit unit) {
if (refreshTask != null) {
refreshTask.cancel(false);
}
refreshTask = scheduler.scheduleAtFixedRate(() -> {
try {
refresh();
} catch (Exception e) {
// 刷新失败日志
}
}, interval, interval, unit);
}
/**
* 初始化调度器
*/
private void initScheduler() {
scheduler = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = new Thread(r, "config-refresh-scheduler");
t.setDaemon(true);
return t;
});
}
/**
* 检测数据类型
*/
private String detectDataType(String value) {
if (value == null) return "string";
try {
Integer.parseInt(value);
return "int";
} catch (NumberFormatException e) {
// Not an int
}
try {
Double.parseDouble(value);
return "double";
} catch (NumberFormatException e) {
// Not a double
}
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
return "boolean";
}
// JSON检查
if (value.trim().startsWith("{") || value.trim().startsWith("[")) {
return "json";
}
return "string";
}
/**
* 获取所有配置
*/
public Map<String, ConfigItem> getAllConfigs() {
lock.readLock().lock();
try {
return new HashMap<>(configs);
} finally {
lock.readLock().unlock();
}
}
/**
* 删除配置
*/
public void removeConfig(String key) {
lock.writeLock().lock();
try {
configs.remove(key);
cache.remove(key);
// 通知监听器
notifyListeners(key, null);
// 从配置源删除
if (source != null) {
source.deleteConfig(key);
}
} finally {
lock.writeLock().unlock();
}
}
/**
* 关闭配置管理器
*/
public void shutdown() {
if (refreshTask != null) {
refreshTask.cancel(true);
}
scheduler.shutdown();
if (source != null) {
source.close();
}
}
}
配置源接口和实现
import java.util.Map;
/**
* 配置源接口
*/
public interface ConfigSource {
Map<String, ConfigItem> loadAllConfigs();
void updateConfig(String key, String value);
void deleteConfig(String key);
void close();
}
/**
* 基于Properties文件的配置源
*/
public class PropertiesConfigSource implements ConfigSource {
private final String filePath;
private final Properties properties = new Properties();
public PropertiesConfigSource(String filePath) {
this.filePath = filePath;
loadProperties();
}
private void loadProperties() {
try (InputStream input = getClass().getClassLoader()
.getResourceAsStream(filePath)) {
if (input != null) {
properties.load(input);
}
} catch (IOException e) {
throw new RuntimeException("Failed to load properties file: " + filePath, e);
}
}
@Override
public Map<String, ConfigItem> loadAllConfigs() {
Map<String, ConfigItem> configMap = new HashMap<>();
for (String key : properties.stringPropertyNames()) {
ConfigItem item = new ConfigItem();
item.setKey(key);
item.setValue(properties.getProperty(key));
item.setGroup("properties");
configMap.put(key, item);
}
return configMap;
}
@Override
public void updateConfig(String key, String value) {
properties.setProperty(key, value);
saveToFile();
}
@Override
public void deleteConfig(String key) {
properties.remove(key);
saveToFile();
}
private void saveToFile() {
// 保存到文件
try (OutputStream output = new FileOutputStream(filePath)) {
properties.store(output, "Config Updated at " + new Date());
} catch (IOException e) {
// 处理异常
}
}
@Override
public void close() {
// 清理资源
}
}
/**
* 基于数据库的配置源
*/
public class DatabaseConfigSource implements ConfigSource {
private final DataSource dataSource;
public DatabaseConfigSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Map<String, ConfigItem> loadAllConfigs() {
Map<String, ConfigItem> configMap = new HashMap<>();
String sql = "SELECT `key`, `value`, `description`, `group_name`, " +
"`is_sensitive`, `data_type` FROM configs";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
ConfigItem item = new ConfigItem(
rs.getString("key"),
rs.getString("value"),
rs.getString("description"),
rs.getString("group_name"),
rs.getBoolean("is_sensitive"),
rs.getString("data_type")
);
configMap.put(item.getKey(), item);
}
} catch (SQLException e) {
throw new RuntimeException("Failed to load configs from database", e);
}
return configMap;
}
@Override
public void updateConfig(String key, String value) {
String sql = "UPDATE configs SET value = ? WHERE `key` = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, value);
ps.setString(2, key);
ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Failed to update config", e);
}
}
@Override
public void deleteConfig(String key) {
String sql = "DELETE FROM configs WHERE `key` = ?";
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, key);
ps.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException("Failed to delete config", e);
}
}
@Override
public void close() {
// 清理资源
}
}
配置缓存实现
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
/**
* 配置缓存
*/
public class ConfigCache {
private final long defaultTtl;
private final Map<String, CacheEntry> cacheMap = new ConcurrentHashMap<>();
private static class CacheEntry {
private final Object value;
private final long expireTime;
CacheEntry(Object value, long expireTime) {
this.value = value;
this.expireTime = expireTime;
}
boolean isExpired() {
return System.currentTimeMillis() > expireTime;
}
}
public ConfigCache(long defaultTtlMillis) {
this.defaultTtl = defaultTtlMillis;
}
public void put(String key, Object value) {
put(key, value, defaultTtl);
}
public void put(String key, Object value, long ttlMillis) {
long expireTime = System.currentTimeMillis() + ttlMillis;
cacheMap.put(key, new CacheEntry(value, expireTime));
}
public Object get(String key) {
CacheEntry entry = cacheMap.get(key);
if (entry == null) return null;
if (entry.isExpired()) {
cacheMap.remove(key);
return null;
}
return entry.value;
}
public void remove(String key) {
cacheMap.remove(key);
}
public void clear() {
cacheMap.clear();
}
public int size() {
return cacheMap.size();
}
}
使用示例
/**
* 配置管理示例代码
*/
public class ConfigExample {
public static void main(String[] args) throws InterruptedException {
// 1. 初始化配置管理器
ConfigManager configManager = ConfigManager.getInstance();
// 2. 配置数据源(这里使用properties文件)
PropertiesConfigSource source = new PropertiesConfigSource("application.properties");
configManager.init(source);
// 3. 添加配置监听器
configManager.registerListener("app.name", (configItem) -> {
System.out.println("App name changed to: " + configItem.getValue());
});
configManager.registerGlobalListener((key) -> {
System.out.println("Config changed: " + key);
});
// 4. 读取配置
String appName = configManager.getConfig("app.name", "MyApp");
int port = configManager.getInt("server.port", 8080);
boolean debug = configManager.getBoolean("app.debug", false);
System.out.println("App Name: " + appName);
System.out.println("Port: " + port);
System.out.println("Debug: " + debug);
// 5. 批量设置配置
Map<String, String> newConfigs = new HashMap<>();
newConfigs.put("server.host", "localhost");
newConfigs.put("server.timeout", "5000");
newConfigs.put("database.poolSize", "20");
configManager.setConfigs(newConfigs);
// 6. 定时刷新配置(每10秒刷新一次)
configManager.scheduleRefresh(10, TimeUnit.SECONDS);
// 7. 模拟运行一段时间
Thread.sleep(30000);
// 8. 关闭配置管理器
configManager.shutdown();
}
}
高级应用:注解驱动的配置绑定
import java.lang.annotation.*;
import java.lang.reflect.Field;
/**
* 配置注解
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ConfigValue {
String key();
String defaultValue() default "";
}
/**
* 配置绑定器
*/
public class ConfigBinder {
public static <T> T bind(T target, ConfigManager configManager) {
Class<?> clazz = target.getClass();
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(ConfigValue.class)) {
ConfigValue annotation = field.getAnnotation(ConfigValue.class);
String value = configManager.getConfig(annotation.key(),
annotation.defaultValue());
field.setAccessible(true);
try {
field.set(target, convertValue(value, field.getType()));
} catch (IllegalAccessException e) {
// 处理异常
}
}
}
return target;
}
private static Object convertValue(String value, Class<?> type) {
if (type == String.class) {
return value;
} else if (type == int.class || type == Integer.class) {
return Integer.parseInt(value);
} else if (type == boolean.class || type == Boolean.class) {
return Boolean.parseBoolean(value);
} else if (type == double.class || type == Double.class) {
return Double.parseDouble(value);
} else if (type == long.class || type == Long.class) {
return Long.parseLong(value);
}
return value;
}
}
/**
* 配置绑定示例
*/
public class AppConfig {
@ConfigValue(key = "app.name", defaultValue = "MyApp")
private String appName;
@ConfigValue(key = "server.port", defaultValue = "8080")
private int port;
@ConfigValue(key = "app.debug", defaultValue = "false")
private boolean debug;
// Getters
public String getAppName() { return appName; }
public int getPort() { return port; }
public boolean isDebug() { return debug; }
public static void main(String[] args) {
ConfigManager configManager = ConfigManager.getInstance();
// 设置一些配置
configManager.setConfig("app.name", "TestApp");
configManager.setConfig("server.port", "9090");
configManager.setConfig("app.debug", "true");
// 绑定配置到对象
AppConfig appConfig = ConfigBinder.bind(new AppConfig(), configManager);
System.out.println("App Name: " + appConfig.getAppName());
System.out.println("Port: " + appConfig.getPort());
System.out.println("Debug: " + appConfig.isDebug());
}
}
配置文件示例 (application.properties)
# 应用配置 app.name=MyApplication app.version=1.0.0 app.debug=false app.environment=development app.timezone=Asia/Shanghai # 服务器配置 server.host=0.0.0.0 server.port=8080 server.maxThreads=200 server.minSpareThreads=50 server.sessionTimeout=30m server.compression.enabled=true # 数据库配置 database.url=jdbc:mysql://localhost:3306/mydb database.username=admin database.password=secret database.poolSize=20 database.maxConnection=100 database.connectionTimeout=3000 database.idleTimeout=60000 # 缓存配置 cache.type=redis cache.host=localhost cache.port=6379 cache.password=redis123 cache.ttl=3600 cache.maxMemory=256MB # 日志配置 logging.level.root=INFO logging.level.com.example=DEBUG logging.file.name=application.log logging.file.maxSize=10MB logging.file.maxHistory=7 # 功能开关 feature.newUI.enabled=true feature.advancedSearch.enabled=false feature.cache.enabled=true feature.rateLimit.enabled=false # 第三方服务配置 sms.provider=aliyun sms.accessKeyId=your-access-key sms.accessKeySecret=your-secret-key sms.signName=YourCompany # 邮件服务配置 mail.smtp.host=smtp.example.com mail.smtp.port=587 mail.smtp.username=user@example.com mail.smtp.password=password mail.from=no-reply@example.com
Maven依赖 (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>config-management</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- SLF4J日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
关键特性说明
- 单例模式:使用双重检查锁实现线程安全的单例
- 读写锁:使用ReentrantReadWriteLock保证并发安全
- 缓存机制:支持配置缓存,提高读取性能
- 监听器模式:支持配置变更监听和通知
- 热更新:支持定时刷新配置,无需重启应用
- 多数据源支持:支持Properties文件、数据库等不同配置源
- 类型转换:自动检测和转换配置值的类型
- 注解驱动:通过注解自动绑定配置到对象
这个配置管理案例提供了完整的实现,您可以按需扩展和调整。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播