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

自动注册XA资源Spring引导

乐正晟
2023-03-14

共有1个答案

颜嘉福
2023-03-14

我通过使用注释和AspectJ方面解决了这个问题。另外,请参见下面的定义,以匹配类级或方法级注释的切入点,您可能需要这样做:

@EnableTransactionManagement(order = Ordered.HIGHEST_PRECEDENCE) 

以便在调用此代码之前发生事务拦截器。

@Aspect
@Component
public class XAResourceAspect {
  @Autowired
  JtaTransactionManager jtaTransactionManager;

  @Autowired
  ApplicationContext applicationContext;

  @Pointcut("within(@XAResource *)")
  public void beanAnnotatedWithAnnotation() {}

  @Pointcut("execution(public * *(..))")
  public void publicMethod() {}

 @Pointcut("publicMethod() && beanAnnotatedWithAnnotation()")
  public void publicMethodInsideAnnotatedClass() {}

  private ThreadLocal<Map<Transaction, Set<String>>> enlistedResources = new ThreadLocal<>();

  @Around("@annotation(ppi.nestup.v3.annotation.XAResource) || publicMethodInsideAnnotatedClass()")
  public Object enlistResources(ProceedingJoinPoint joinPoint) throws Throwable {
    boolean setThreadLocal = false;
    Transaction transaction = jtaTransactionManager.getTransactionManager().getTransaction();
    if (transaction != null) {
      Map<Transaction, Set<String>> transactionMap = enlistedResources.get();
      LOG.info("Enlisting resources for joinpoint " + joinPoint + " and transaction " + transaction);
      if (transactionMap == null) {
        transactionMap = new HashMap<>();
        enlistedResources.set(transactionMap);
        setThreadLocal = true;
        LOG.info("Created new ThreadLocal for transaction " + transaction);
      } else {
        LOG.info("Found existing ThreadLocal " + transactionMap);
      }
      transactionMap.computeIfAbsent(transaction, k -> new HashSet<>());
      MethodSignature signature = (MethodSignature) joinPoint.getSignature();
      Method method = signature.getMethod();
      Class withinType = joinPoint.getSourceLocation().getWithinType();

      XAResource annotation = method.getAnnotation(XAResource.class);
      if (annotation == null) {
        annotation = (XAResource) withinType.getAnnotation(XAResource.class);
      }
      String[] resourceNames = annotation.value();
      for (String name : resourceNames) {
        if (!transactionMap.get(transaction).contains(name)) {
          javax.transaction.xa.XAResource resource =
            (javax.transaction.xa.XAResource) applicationContext.getBean(name);
          try {
            transaction.enlistResource(resource);
          } catch (IllegalStateException e) {
            LOG.error("Caught exception trying to enlist resource " + name + " for transaction " + transaction + " and joinpoint " + joinPoint);
            e.printStackTrace();
          }
          transactionMap.get(transaction).add(name);
        }
      }
    }

    Object proceed = joinPoint.proceed();
    if (setThreadLocal) {
      LOG.info("Removing threadlocal");
      enlistedResources.remove();
    }
    return proceed;
  }
}

我还没有做很多测试,但它的工作到目前为止。

 类似资料:
  • void register_resource(string name, array resource_funcs) Use this to dynamically register a resource plugin with Smarty. Pass in the name of the resource and the array of PHP functions implementing i

  • 那么我的问题是,@javax为什么会这样做。注释。资源工作,但@AutoWired没有工作。为了在Restful控制器上进行测试,我尝试将MappingJackson2HttpMessageConverter注入@Autowired,在启动时,容器未能找到符合条件的bean,即使该类位于路径上。现在,为了解决这个问题,我进入了一个上下文xml文件并添加了bean: 然后在测试类中有成员变量: 然后

  • 和和注释之间有什么区别? 我们应该在什么时候使用它们每一个?

  • 我有一个web应用程序,它将从jar文件动态加载其资源。 我必须如何重新编写加载和注册资源并启动服务器的主类,以便它在web应用程序内部工作? 我目前定义了一个,它在标记为的方法中加载资源。虽然这是有效的,但它会随着每个请求初始化。 我尝试将添加到应用程序中,但这导致了错误: 我的做法是完全错误的吗?或者如何创建这样一个系统,作为可部署的war运行? *编辑* 通过使用ServletContext

  • 我想知道最好的方法是什么。 我正计划在我的移动应用程序中使用linkedin、谷歌登录和密码认证。此社交登录应连接到我的数据库中的用户。 我的spring应用程序将充当一个API,应该使用JWT令牌来保护它。移动应用程序随后将使用此JWT令牌来使用API。 这是正确的吗?我没有找到任何关于如何最好地使用spring social实现这一点的信息,以及spring social是否支持这个用例。 谁

  • 我决定在这部分替换Web.XML: 我指向servlet容器Jersey,它将接受对REST-Controllers的请求,表明在启动时有必要扫描路径com . skillsimprover . REST examples . REST上的包REST,并表明资源的所有方法和类的基URI都填充了/api/* 从 JAX-RS 2.x 版本开始,可以使用应用程序类或资源配置类来注册包和资源。 我执行了