首页 > 其他分享 >引入两个依赖,存在相同bean,导致启动失败

引入两个依赖,存在相同bean,导致启动失败

时间:2024-04-03 17:35:26浏览次数:19  
标签:依赖 tobato fastdfs groupName bean command 引入 import com

场景描述

OpenFeign和FastDFS都存在connectionManager这个类,导致spring在加载bean名称冲突。

解决方案

网上的解决方案有很多,都一一尝试过,但是无法解决。

最后解决方案:采用全类名覆盖加载


资料信息:

JVM优先加载项目中的类而不是依赖包里的类,这主要基于Java的类加载机制中的双亲委派模型以及类加载器的工作原理。

双亲委派模型是Java类加载器的工作原则。当一个类加载器收到类加载的请求时,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成。每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中。只有当父类加载器无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

整体思路解析

查看FastDFS源码结构

因为我们采用方案是修改connectionManager的bean名,从而避免bean名称冲突问题,所以主要注入了connectionManager的类,都要进行覆盖。

相关代码

除了标注出来的地方,其他都是保持和源码一模一样。

ConnectionManager

关键:

  1. 在自己项目中创建com.github.tobato.fastdfs.con包;
  2. 修改ConnectionManager的bean名称,如:@Component("FastDFSConnectionManager")
**package com.github.tobato.fastdfs.conn;**

import java.net.InetSocketAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.github.tobato.fastdfs.exception.FdfsException;
import com.github.tobato.fastdfs.proto.FdfsCommand;

/**
 * 连接池管理
 *
 * <pre>
 * 负责借出连接,在连接上执行业务逻辑,然后归还连
 * </pre>
 *
 * @author tobato
 *
 */
**@Component("FastDFSConnectionManager")**
public class ConnectionManager {

    /** 连接池 */
    @Autowired
    private FdfsConnectionPool pool;
    /** 日志 */
    protected static final Logger LOGGER = LoggerFactory.getLogger(ConnectionManager.class);

    /**
     * 构造函数
     */
    public ConnectionManager() {
        super();
    }

    /**
     * 构造函数
     *
     * @param pool
     */
    public ConnectionManager(FdfsConnectionPool pool) {
        super();
        this.pool = pool;
    }

    /**
     * 获取连接并执行交易
     *
     * @param address
     * @param command
     * @return
     */
    public <T> T executeFdfsCmd(InetSocketAddress address, FdfsCommand<T> command) {

        // 获取连接
        Connection conn = getConnection(address);
        // 执行交易
        return execute(address, conn, command);

    }

    /**
     * 执行交易
     *
     * @param conn
     * @param command
     * @return
     */
    protected <T> T execute(InetSocketAddress address, Connection conn, FdfsCommand<T> command) {
        try {
            // 执行交易
            LOGGER.debug("对地址{}发出交易请求{}", address, command.getClass().getSimpleName());
            return command.execute(conn);
        } catch (FdfsException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("execute fdfs command error", e);
            throw new RuntimeException("execute fdfs command error", e);
        } finally {
            try {
                if (null != conn) {
                    pool.returnObject(address, conn);
                }
            } catch (Exception e) {
                LOGGER.error("return pooled connection error", e);
            }
        }
    }

    /**
     * 获取连接
     *
     * @param address
     * @return
     */
    protected Connection getConnection(InetSocketAddress address) {
        Connection conn = null;
        try {
            // 获取连接
            conn = pool.borrowObject(address);
        } catch (FdfsException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("Unable to borrow buffer from pool", e);
            throw new RuntimeException("Unable to borrow buffer from pool", e);
        }
        return conn;
    }

    public FdfsConnectionPool getPool() {
        return pool;
    }

    public void setPool(FdfsConnectionPool pool) {
        this.pool = pool;
    }

    public void dumpPoolInfo(InetSocketAddress address) {

        LOGGER.debug("==============Dump Pool Info================");
        LOGGER.debug("活动连接{}", pool.getNumActive(address));
        LOGGER.debug("空闲连接{}", pool.getNumIdle(address));
        LOGGER.debug("连接获取总数统计{}", pool.getBorrowedCount());
        LOGGER.debug("连接返回总数统计{}", pool.getReturnedCount());
        LOGGER.debug("连接销毁总数统计{}", pool.getDestroyedCount());

    }

}

DefaultGenerateStorageClient

关键:

  1. 在自己项目中创建com.github.tobato.fastdfs.con包;
  2. 因为修改了bean名称了,所以需要修改注入bean名称,如:@Resource(name = "FastDFSConnectionManager")
package com.github.tobato.fastdfs.service;

import java.io.InputStream;
import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import com.github.tobato.fastdfs.conn.ConnectionManager;
import com.github.tobato.fastdfs.domain.FileInfo;
import com.github.tobato.fastdfs.domain.MateData;
import com.github.tobato.fastdfs.domain.StorageNode;
import com.github.tobato.fastdfs.domain.StorageNodeInfo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.proto.storage.DownloadCallback;
import com.github.tobato.fastdfs.proto.storage.StorageDeleteFileCommand;
import com.github.tobato.fastdfs.proto.storage.StorageDownloadCommand;
import com.github.tobato.fastdfs.proto.storage.StorageGetMetadataCommand;
import com.github.tobato.fastdfs.proto.storage.StorageQueryFileInfoCommand;
import com.github.tobato.fastdfs.proto.storage.StorageSetMetadataCommand;
import com.github.tobato.fastdfs.proto.storage.StorageUploadFileCommand;
import com.github.tobato.fastdfs.proto.storage.StorageUploadSlaveFileCommand;
import com.github.tobato.fastdfs.proto.storage.enums.StorageMetdataSetType;

/**
 * 基本存储客户端操作实现
 *
 * @author tobato
 *
 */
@Component
@Primary
public class DefaultGenerateStorageClient implements GenerateStorageClient {

    /** trackerClient */
    @Resource
    protected TrackerClient trackerClient;

    /** connectManager */
    **@Resource(name = "FastDFSConnectionManager")**
    protected ConnectionManager connectionManager;

    /** 日志 */
    protected static Logger LOGGER = LoggerFactory.getLogger(DefaultGenerateStorageClient.class);

    /**
     * 上传不支持断点续传的文件
     */
    @Override
    public StorePath uploadFile(String groupName, InputStream inputStream, long fileSize, String fileExtName) {
        StorageNode client = trackerClient.getStoreStorage(groupName);
        StorageUploadFileCommand command = new StorageUploadFileCommand(client.getStoreIndex(), inputStream,
                fileExtName, fileSize, false);
        return connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 上传从文件
     */
    @Override
    public StorePath uploadSlaveFile(String groupName, String masterFilename, InputStream inputStream, long fileSize,
                                     String prefixName, String fileExtName) {
        StorageNodeInfo client = trackerClient.getUpdateStorage(groupName, masterFilename);
        StorageUploadSlaveFileCommand command = new StorageUploadSlaveFileCommand(inputStream, fileSize, masterFilename,
                prefixName, fileExtName);
        return connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 获取metadata
     */
    @Override
    public Set<MateData> getMetadata(String groupName, String path) {
        StorageNodeInfo client = trackerClient.getFetchStorage(groupName, path);
        StorageGetMetadataCommand command = new StorageGetMetadataCommand(groupName, path);
        return connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 覆盖metadata
     */
    @Override
    public void overwriteMetadata(String groupName, String path, Set<MateData> metaDataSet) {
        StorageNodeInfo client = trackerClient.getUpdateStorage(groupName, path);
        StorageSetMetadataCommand command = new StorageSetMetadataCommand(groupName, path, metaDataSet,
                StorageMetdataSetType.STORAGE_SET_METADATA_FLAG_OVERWRITE);
        connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 合并metadata
     */
    @Override
    public void mergeMetadata(String groupName, String path, Set<MateData> metaDataSet) {
        StorageNodeInfo client = trackerClient.getUpdateStorage(groupName, path);
        StorageSetMetadataCommand command = new StorageSetMetadataCommand(groupName, path, metaDataSet,
                StorageMetdataSetType.STORAGE_SET_METADATA_FLAG_MERGE);
        connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 查询文件信息
     */
    @Override
    public FileInfo queryFileInfo(String groupName, String path) {
        StorageNodeInfo client = trackerClient.getFetchStorage(groupName, path);
        StorageQueryFileInfoCommand command = new StorageQueryFileInfoCommand(groupName, path);
        return connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 删除文件
     */
    @Override
    public void deleteFile(String groupName, String path) {
        StorageNodeInfo client = trackerClient.getUpdateStorage(groupName, path);
        StorageDeleteFileCommand command = new StorageDeleteFileCommand(groupName, path);
        connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    /**
     * 下载整个文件
     */
    @Override
    public <T> T downloadFile(String groupName, String path, DownloadCallback<T> callback) {
        long fileOffset = 0;
        long fileSize = 0;
        return downloadFile(groupName, path, fileOffset, fileSize, callback);
    }

    /**
     * 下载文件片段
     */
    @Override
    public <T> T downloadFile(String groupName, String path, long fileOffset, long fileSize,
                              DownloadCallback<T> callback) {
        StorageNodeInfo client = trackerClient.getFetchStorage(groupName, path);
        StorageDownloadCommand<T> command = new StorageDownloadCommand<T>(groupName, path, 0, 0, callback);
        return connectionManager.executeFdfsCmd(client.getInetSocketAddress(), command);
    }

    public void setTrackerClientService(TrackerClient trackerClientService) {
        this.trackerClient = trackerClientService;
    }

    public void setConnectionManager(ConnectionManager connectionManager) {
        this.connectionManager = connectionManager;
    }

}

标签:依赖,tobato,fastdfs,groupName,bean,command,引入,import,com
From: https://www.cnblogs.com/chenliugou/p/18113183

相关文章

  • Java登陆第三十六天——VUE3引入CSS
    在一个.Vue文件中,通常包括以下三部分。<template><style><script>.vue中部分传统部分描述<template>HTML代替传统的.html文件<style>CSS代替传统的.js文件<script>JS代替传统的.css文件声明内部的CSS在.Vue文件中,style标签声明CSS。Hello......
  • Spring默认BeanName
    先说结论:1、XML配置和注解生成默认BeanName的机制是不同的2、XML配置默认BeanName=全类名+#+数字,如com.anyway.p2024.service.impl.BigHouseServiceImpl#03、注解默认BeanName=短类名首字母变成小写,如bigHouseServiceImpl注意:如果短类名前2个字母都是大写,则保持短类......
  • 在VS或者CLion中引入C和C++的SDK
    visualstudio创建c++项目引入头文件和库文件拷贝的gpt的,可以用在VisualStudio2022中,虽然你创建的是一个C++项目,但它确实支持C语言的编译和运行。为了在你的项目中使用C语言的头文件和库文件,你可以按照以下步骤操作:1.**添加头文件和库文件到项目:**-首先,你......
  • vue引入vue-router
    Vue路由(router)的安装和使用安装vue-router插件第一步:在CMD窗口中,使用命令跳转到vue的安装路径下第二步:输入命令:npmivue-router@3vue2要安装vue-router3npmivue-router@3vu3要安装vue-router4npmivue-router@4第三步:出现added1packagein2m表示安装成功vu......
  • 搜索Maven相关依赖jar包(特别推荐)https://mvnrepository.com/
    搜索Maven相关依赖jar包(特别推荐)https://mvnrepository.com/根据maven查询jar包的步骤如下:打开Maven仓库中央库的网站https://mvnrepository.com/在搜索框中输入你需要查询的jar包的名称,例如:hutool-all点击搜索按钮,网站会列出所有符合条件的jar包信息,包括版本号、最近更新时间......
  • Java里如何查找第三方包/依赖的api文档
    Java里如何查找第三方包/依赖的api文档众所周知,要查找第三方包的api介绍说明,在golang里,直接去这个网站搜索即可:https://pkg.go.dev/​pkg.go.dev/在Python里则是去PyPi:PyPI·ThePythonPackageIndex(详细方法见此文:东写西读:Python从入门到成神必须知道的找包方法可......
  • ARM架构银河麒麟使用笔记-下载docker软件包及所有依赖包并在离线环境下安装
    ARM架构银河麒麟使用笔记-下载docker软件包及所有依赖包并在离线环境下安装arm银河麒麟aptdocker目的是在arm架构的银河麒麟操作系统V10中安装docker。一、给虚拟机创建快照1.创建qemu-imgsnapshot-cEmptyKylinrootfs.qcow22.查看qemu-imgsnapshot-lrootfs......
  • 【异常】Spring的依赖注入(DI)系统提示异常,因为漏了一个实现类导致了错误Parameter 0 of
    一、异常内容2024-04-0111:44:39.912[main]ERRORorg.springframework.boot.diagnostics.LoggingFailureAnalysisReporter-***************************APPLICATIONFAILEDTOSTART***************************Description:Parameter0ofconstructorinc......
  • JMeter前置处理器-Beanshell前置处理器详解
    前言在JMeter中,前置处理器用于在发送HTTP请求之前执行特定的操作。Beanshell前置处理器是一种非常强大的前置处理器,它允许您使用Java语言编写脚本来实现各种复杂的逻辑。本文将介绍如何使用Beanshell前置处理器来执行自定义操作以增强性能测试。什么是Beanshell前置处理器?Bean......
  • 引入了 Shiro 的项目请求路径中带有中文报错400 的问题
    byemanjusakafromhttps://www.emanjusaka.top/2024/04/shiro-request-chinese-error-400彼岸花开可奈何本文欢迎分享与聚合,全文转载请留下原文地址。当我们的项目中引入了Shiro后,带有中文的请求路径会被拦截并返回400的错误。一般我们的请求路径是不会带有中文字符,但......