当前位置: 首页 > 知识库问答 >
问题:

委托DataSourceSpring引导

阳德润
2023-03-14
 org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dataSource': Requested bean is currently in creation: Is there an unresolvable circular reference?

编辑1:AOP-我尝试添加pointcut执行(public*javax.sql.datasource+.getConnection(..))。这仅在Spring datasource与用户名/密码一起使用时才起作用。一旦我用JNDI在Jboss中部署,我就会得到WildFlyDataSource代理错误。因此,我考虑使用delegatingDataSource而不是AOP方法

   // AOP Example

    @Pointcut("execution(public * javax.sql.DataSource+.getConnection(..))")
    void prepareConnectionPointcut() {
        logger.debug("prepareConnectionPointcut");
    }
    
    @AfterReturning(pointcut = "prepareConnectionPointcut()", returning = "connection")
    void afterPrepareConnection(Connection connection) {
        // Set context in Connection - return same connection for query execution
    }

但是当我在JBoss中部署这段代码时--我会得到WildFlyDataSource datasource bean创建错误。

创建名为'org.springframework.boot.autoconfigure.orm.jpa.Hibernatejpaconfiguration'的bean时出错:通过构造函数参数0表示的依赖项不满足;嵌套异常是org.springframework.beans.factory.beanCreationException:创建类路径资源[org/springframework/boot/autoconfiguration/jdbc/jndidatasourceautoconfiguration.class]中定义的名称为“data source”的bean时出错:bean初始化失败;嵌套异常是org.springframework.aop.framework.aopconfigException:无法生成org.jboss.as.connector.subsystems.datasources.wildflydatasource类的CGLIB子类:此问题的常见原因包括使用最终类或不可见类;嵌套异常是org.springframework.cglib.core.codeGenerationException:java.lang.noClassDefFounderRor-->org/jboss/as/connector/subsystems/datasources/WildFlyDataSource

我还在初始化期间添加了proxyTargetClass标志

@enableAspectJAutoProxyProxtargetClass=true

共有1个答案

西门良才
2023-03-14

感谢@M.Deinum推荐使用BeanPostProcessor&实现DelegatingDataSource来设置客户端信息。请找到下面的代码片段,我在Spring Boot中实现了这一点,它可以很好地与JBoos、JNDI连接或Spring Boot URL数据源连接一起工作。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    private static Logger logger = LoggerFactory.getLogger(MyBeanPostProcessor.class);

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if (bean instanceof DataSource) {
            // Check DataSource bean initialization & enclose it with DelegatingDataSource 
            logger.debug("MyBeanPostProcessor:: postProcessAfterInitialization:: DataSource");

            DataSource beanDs = (DataSource) bean;
            return new MyDelegateDS(beanDs);
        }

        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DataSource) {
            logger.debug("MyBeanPostProcessor:: postProcessBeforeInitialization:: DataSource");
        }

        logger.debug("MyBeanPostProcessor:: postProcessBeforeInitialization:: " + beanName);

        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

}

我实现delegatingDataSource来处理每个用户请求以在DB连接会话中设置客户端上下文

 public class MyDelegateDS extends DelegatingDataSource {

    private static Logger logger = LoggerFactory.getLogger(MyDelegateDS.class);

    public MyDelegateDS(DataSource delegate) {
        super(delegate);
        logger.debug("MyDelegateDS:: constructor");
    }

    @Override
    public Connection getConnection() throws SQLException {
        logger.debug("MyDelegateDS:: getConnection");

        // To do this context only for user Request - to avoid this during Server initialization
        if (RequestContextHolder.getRequestAttributes() != null
                && ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest() != null) {

            logger.debug("MyDelegateDS:: getConnection: valid user request");

            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
                    .getRequest();
                    
            // Checking each user request & calling SP to set client context before invoking actual native query/SP
        }

        logger.debug("MyDelegateDS:: getConnection: Not User Request");

        return super.getConnection();
    }

}

希望这对面临同样问题的人有所帮助

 类似资料:
  • 主要内容:类委托,属性委托,标准委托,可观察属性 Observable,把属性储存在映射中,Not Null,局部委托属性,属性委托要求,翻译规则,提供委托委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。 Kotlin 直接支持委托模式,更加优雅,简洁。Kotlin 通过关键字 by 实现委托。 类委托 类的委托即一个类中定义的方法实际是调用另一个类的对象的方法来实现的。 以下实例中派生类 Derived 继承了接口

  • 主要内容:声明委托,实例化委托,多播委托(合并委托)C# 中的委托(Delegate)类似于 C 或 C++ 中的函数指针,是一种引用类型,表示对具有特定参数列表和返回类型的方法的引用。委托特别适用于实现事件和回调方法,所有的委托都派生自 System.Delegate 类。在实例化委托时,可以将委托的实例与具有相同返回值类型的方法相关联,这样就可以通过委托来调用方法。另外,使用委托还可以将方法作为参数传递给其他方法, 委托具有以下特点: 委托类似

  • 关于“行为委派”的良好讨论可以在 找到。

  • 委托模式是软件设计模式中的一项基本技巧。在委托模式中,有两个对象参与处理同一个请求,接受请求的对象将请求委托给另一个对象来处理。 Kotlin 直接支持委托模式,更加优雅,简洁。Kotlin 通过关键字 by 实现委托。 类委托 类的委托即一个类中定义的方法实际是调用另一个类的对象的方法来实现的。 以下实例中派生类 Derived 继承了接口 Base 所有方法,并且委托一个传入的 Base 类的

  • 问题内容: 我在Web应用程序中使用jQuery。在阅读其文档时,我了解了和。尽管他们解释了这两种方法,但我不了解它们之间的确切区别。也不确定哪种方法在哪种情况下是理想的。 请帮助我清楚地了解这些方法。 谢谢 问题答案: 要求您立即运行选择器,除非您使用的结果非常浪费。这里的事件处理程序是附加到的,因此必须检查所有冒泡的该类型事件。这是一个用法示例: 请注意, 即使我们不在乎 该语句,该选择符 也

  • 如果没有,是否有一种简洁的方法来设置类加载器的上下文(比方说,从特定类/库调用的所有内容都应该使用相同的类加载器)。