Spring Boot连接Hadoop HBase失败 求可运行示例项目
Spring Boot集成HBase可运行示例及问题解决
问题描述
报错信息:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'feedService': Unsatisfied dependency expressed through field 'hbaseTemplate': Error creating bean with name 'hbaseTemplate' defined in class path resource [com/example/demo/HbaseConfig.class]: Failed to instantiate [org.springframework.data.hadoop.hbase.HbaseTemplate]: Factory method 'hbaseTemplate' threw exception with message: org/apache/hadoop/hbase/client/HTableInterface
核心原因:spring-data-hadoop:2.5.0.RELEASE适配的是HBase 1.x版本,而你使用的HBase 2.5.2已移除HTableInterface类(替换为Table接口),版本不兼容导致该错误。
你的现有依赖配置
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-hadoop</artifactId> <version>2.5.0.RELEASE</version> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase</artifactId> <version>2.5.2</version> <type>pom</type> </dependency> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>2.5.2</version> <scope>compile</scope> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>
你的现有HBase连接类代码
public class HConnection { private String hbasezookeeperquorum = "PRODDMSDN04";// ,proddmsdn02,proddmsdn01 private String hbasezookeeperpropertyclientPort = "2181"; private String hbasemaster = "proddmsdn01:16010"; private String zookeeperznodeparent = "/hbase-unsecure"; private String dmshbasetable="DMSMASTER"; private String dmshbasetableimgfamily="img"; private String dmshbasetabledatafamily="data"; private String dmshbasetablemetafamily="meta"; static Configuration conf; static Connection connection; private String dmsid="1a2c3e0e-8363-4e94-87c9-701029933b37"; private Connection newConnection() { Connection conn = null; try { conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", hbasezookeeperquorum); conf.set("hbase.zookeeper.property.clientPort", hbasezookeeperpropertyclientPort); conf.set("hbase.master", hbasemaster); conf.set("zookeeper.znode.parent", zookeeperznodeparent); conn = ConnectionFactory.createConnection(conf); System.out.println("conn" + conn.getConfiguration()); } catch (Exception e) { System.out.println(e.getMessage()); } return conn; } public static void main(String[] args) throws IOException, URISyntaxException, Exception { System.out.println("Connecting to Hadoop------->"); connection=new HConnection().newConnection(); FileSystem fileSystem = FileSystem.get(conf); if (fileSystem instanceof DistributedFileSystem) { System.out.println("HDFS is the underlying filesystem"); HashMap<String, String> map = new HashMap<>(); } else { System.out.println("Other type of file system " + fileSystem.getClass()); System.out.println("Filesystem connected------->"); } } ArrayList<Map<String, String>> list = new ArrayList<>(); public Optional<List<Map<String, String>>> searchMetaData(Map<String, String> searchParams) throws IOException { System.out.println("searchParams-------------->"+searchParams); TableName tablename = TableName.valueOf(dmshbasetable); Table table = connection.getTable(tablename); System.out.println("Connecting table-------------->"+table); Scan scan = new Scan(); scan.addFamily(Bytes.toBytes(dmshbasetabledatafamily)); scan.addFamily(Bytes.toBytes(dmshbasetablemetafamily)); FilterList allFilters = new FilterList(new Filter[0]); for (Map.Entry<String, String> entry : searchParams.entrySet()) { SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes(dmshbasetablemetafamily), Bytes.toBytes(entry.getKey()), CompareFilter.CompareOp.EQUAL, Bytes.toBytes(entry.getValue())); allFilters.addFilter((Filter) filter); } SingleColumnValueFilter filter2 = new SingleColumnValueFilter(Bytes.toBytes(dmshbasetabledatafamily), Bytes.toBytes("status"), CompareFilter.CompareOp.EQUAL, Bytes.toBytes("1")); allFilters.addFilter((Filter) filter2); scan.setFilter((Filter) allFilters); ResultScanner resultScanner = table.getScanner(scan); Iterator<Result> arr = resultScanner.iterator(); list = new ArrayList<>(); while (arr.hasNext()) { Get g = new Get(((Result) arr.next()).getRow()); Result result = table.get(g); Map<String, String> map = new HashMap<>(); NavigableMap<byte[], byte[]> data = result.getFamilyMap(Bytes.toBytes(dmshbasetabledatafamily)); NavigableMap<byte[], byte[]> metadata = result.getFamilyMap(Bytes.toBytes(dmshbasetablemetafamily)); data.putAll(metadata); for (Map.Entry<byte[], byte[]> entry : data.entrySet()) map.put(new String(entry.getKey()), new String(entry.getValue())); list.add(map); } if (list.isEmpty()) return Optional.empty(); List<JSONObject> jsonObj = new ArrayList<JSONObject>(); for(Map<String, String> data : list) { JSONObject obj = new JSONObject(data); jsonObj.add(obj); } JSONArray test = new JSONArray(jsonObj); System.out.println(test.toString()); writeCSV(test.toString()); return Optional.of(list); } private void writeCSV(String list) { try (PrintWriter writer = new PrintWriter(new File("hadoopconnection_test.csv"))) { StringBuilder stringbuilder = new StringBuilder(); stringbuilder.append("DMSid"); stringbuilder.append(','); stringbuilder.append("Payload"); stringbuilder.append('\n'); stringbuilder.append(dmsid); stringbuilder.append(','); stringbuilder.append(list); stringbuilder.append('\n'); writer.write(stringbuilder.toString()); System.out.println("Data Imported to CSV successfully Done------->"); } catch (FileNotFoundException exception) { System.out.println(exception.getMessage()); } } }
可运行的Spring Boot集成HBase示例
1. 调整依赖(移除spring-data-hadoop,使用原生HBase客户端)
<!-- Spring Boot基础依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- HBase客户端 --> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>2.5.2</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <!-- 排除冲突的Hadoop依赖 --> <exclusion> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> </exclusion> </exclusions> </dependency> <!-- 适配HBase版本的Hadoop common --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.3.4</version> <exclusions> <exclusion> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>
2. HBase配置类(Spring统一管理连接)
import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.io.IOException; @Configuration public class HBaseConfig { @Value("${hbase.zookeeper.quorum}") private String zookeeperQuorum; @Value("${hbase.zookeeper.property.clientPort}") private String zookeeperPort; @Value("${zookeeper.znode.parent}") private String znodeParent; @Bean public org.apache.hadoop.conf.Configuration hbaseConfig() { org.apache.hadoop.conf.Configuration config = HBaseConfiguration.create(); config.set("hbase.zookeeper.quorum", zookeeperQuorum); config.set("hbase.zookeeper.property.clientPort", zookeeperPort); config.set("zookeeper.znode.parent", znodeParent); return config; } @Bean(destroyMethod = "close") public Connection hbaseConnection() throws IOException { return ConnectionFactory.createConnection(hbaseConfig()); } }
3. 配置文件(application.yml)
hbase: zookeeper: quorum: PRODDMSDN04,proddmsdn02,proddmsdn01 property: clientPort: 2181 znode: parent: /hbase-unsecure
4. HBase操作Service
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.filter.CompareFilter; import org.apache.hadoop.hbase.filter.FilterList; import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; import org.apache.hadoop.hbase.util.Bytes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @Service public class HBaseService { private final Connection hbaseConnection; private static final String TABLE_NAME = "DMSMASTER"; private static final String FAMILY_DATA = "data"; private static final String FAMILY_META = "meta"; @Autowired public HBaseService(Connection hbaseConnection) { this.hbaseConnection = hbaseConnection; } public Optional<List<Map<String, String>>> searchMetaData(Map<String, String> searchParams) throws IOException { List<Map<String, String>> resultList = new ArrayList<>(); try (Table table = hbaseConnection.getTable(TableName.valueOf(TABLE_NAME))) { Scan scan = new Scan(); scan.addFamily(Bytes.toBytes(FAMILY_DATA)); scan.addFamily(Bytes.toBytes(FAMILY_META)); FilterList filterList = new FilterList(); // 添加搜索参数过滤 for (Map.Entry<String, String> entry : searchParams.entrySet()) { SingleColumnValueFilter filter = new SingleColumnValueFilter( Bytes.toBytes(FAMILY_META), Bytes.toBytes(entry.getKey()), CompareFilter.CompareOp.EQUAL, Bytes.toBytes(entry.getValue()) ); filterList.addFilter(filter); } // 添加状态过滤 SingleColumnValueFilter statusFilter = new SingleColumnValueFilter( Bytes.toBytes(FAMILY_DATA), Bytes.toBytes("status"), CompareFilter.CompareOp.EQUAL, Bytes.toBytes("1") ); filterList.addFilter(statusFilter); scan.setFilter(filterList); try (ResultScanner scanner = table.getScanner(scan)) { for (Result result : scanner) { Map<String, String> rowMap = new HashMap<>(); // 读取data列族数据 result.getFamilyMap(Bytes.toBytes(FAMILY_DATA)).forEach((k, v) -> rowMap.put(Bytes.toString(k), Bytes.toString(v)) ); // 读取meta列族数据 result.getFamilyMap(Bytes.toBytes(FAMILY_META)).forEach((k, v) -> rowMap.put(Bytes.toString(k), Bytes.toString(v)) ); resultList.add(rowMap); } } } return resultList.isEmpty() ? Optional.empty() : Optional.of(resultList); } }
5. 测试Controller
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Optional; @RestController public class HBaseController { @Autowired private HBaseService hBaseService; @GetMapping("/search") public String searchMetaData(@RequestParam Map<String, String> searchParams) throws IOException { Optional<List<Map<String, String>>> result = hBaseService.searchMetaData(searchParams); return result.map(Object::toString).orElse("无匹配数据"); } }
关键优化说明
- 版本兼容:移除
spring-data-hadoop,直接使用HBase 2.x原生客户端,彻底解决API不兼容问题。 - 连接管理:将HBase Connection配置为Spring Bean,由Spring负责生命周期管理,避免手动管理连接的线程安全问题。
- 资源安全:使用try-with-resources语法自动关闭Table、ResultScanner等资源,防止资源泄漏。
- 配置解耦:将HBase配置移至application.yml,便于不同环境切换配置。
内容的提问来源于stack exchange,提问作者Kalyani Mvn
相关产品推荐
相关产品推荐

