Spring boot Springboot@Transactional-如何在创建服务代理时使spring调用超级化?

Spring boot Springboot@Transactional-如何在创建服务代理时使spring调用超级化?,spring-boot,transactions,cglib,Spring Boot,Transactions,Cglib,我在Springboot方面有中级技能,可以开发简单到中等复杂的应用程序,但这一点让我有点扫兴 我有一个@Service扩展了Guava的AbstractIdleService,还有一个@Controller自动连接了该服务的实例 在服务中,我有一个方法,比如performTransaction(),它用@Transactional注释(当然是让Spring处理事务),它确实创建了服务类的代理。但是当我调试应用程序时,我可以看到注入控制器中的代理包含所有super class(AbstractI

我在Springboot方面有中级技能,可以开发简单到中等复杂的应用程序,但这一点让我有点扫兴

我有一个@Service扩展了Guava的AbstractIdleService,还有一个@Controller自动连接了该服务的实例

在服务中,我有一个方法,比如performTransaction(),它用@Transactional注释(当然是让Spring处理事务),它确实创建了服务类的代理。但是当我调试应用程序时,我可以看到注入控制器中的代理包含所有super class(AbstractIdleService)类字段,因为null表示在创建服务的代理时不会调用super()。因此,在调用超类(AbstractIdleService)的startAsync方法时,应用程序无法初始化。我真的不知道该怎么做

我在下面添加了一些代码以进行说明。 这是我的服务课:

import com.google.common.util.concurrent.AbstractIdleService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyService extends AbstractIdleService {
  @Transactional
  public void performTransaction() {
  }
}
这是使用上述服务的控制器:

@Controller
public void MyController {
    private MyService service;
    private EurekaRegistration eurekaRegistration;
    
    @Autowired
    public MyController(MyService service, EurekaRegistration eurekaRegistration) {
        this.service = service;     // This is where the proxy contains all AbstractIdleService fields null
        this.eurekaRegistration = eurekaRegistration;
    }

    @EventListener({ ApplicationPreparedEvent.class })
        public void handleApplicationPreparedEvent() {
        this.service.startAsync();  // This line throws NPE, as delegate in the parent is null
        this.service.awaitRunning();
    }
}

我必须使用AbstractIdleService,因为这是组织约定,我需要在startAsync方法中调用一些启动代码。但在服务上调用startAsync方法会导致NullPointerException,因为它使用的父字段为null,因为代理初始化从未调用super。

我不能100%确定这是否是实际问题,但请尝试类似的方法(未测试):

代理服务器的接口:

import com.google.common.util.concurrent.Service;

public interface MyService extends Service {

  void performTransaction();
}
实施:

import com.google.common.util.concurrent.AbstractIdleService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyServiceImpl extends AbstractIdleService implements MyService {
  @Transactional
  public void performTransaction() {
  }
}
@Controller
public void MyController {
    private MyService service;
    private EurekaRegistration eurekaRegistration;
    
    @Autowired
    public MyControlle(MyService service, EurekaRegistration eurekaRegistration) {
        this.service = service;
        this.eurekaRegistration = eurekaRegistration;
    }
}
控制器,声明服务接口,而不是实现:

import com.google.common.util.concurrent.AbstractIdleService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyServiceImpl extends AbstractIdleService implements MyService {
  @Transactional
  public void performTransaction() {
  }
}
@Controller
public void MyController {
    private MyService service;
    private EurekaRegistration eurekaRegistration;
    
    @Autowired
    public MyControlle(MyService service, EurekaRegistration eurekaRegistration) {
        this.service = service;
        this.eurekaRegistration = eurekaRegistration;
    }
}

我不能100%确定这是否是实际问题,但请尝试类似的方法(未经测试):

代理服务器的接口:

import com.google.common.util.concurrent.Service;

public interface MyService extends Service {

  void performTransaction();
}
实施:

import com.google.common.util.concurrent.AbstractIdleService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyServiceImpl extends AbstractIdleService implements MyService {
  @Transactional
  public void performTransaction() {
  }
}
@Controller
public void MyController {
    private MyService service;
    private EurekaRegistration eurekaRegistration;
    
    @Autowired
    public MyControlle(MyService service, EurekaRegistration eurekaRegistration) {
        this.service = service;
        this.eurekaRegistration = eurekaRegistration;
    }
}
控制器,声明服务接口,而不是实现:

import com.google.common.util.concurrent.AbstractIdleService;
import org.springframework.transaction.annotation.Transactional;

@Service
public class MyServiceImpl extends AbstractIdleService implements MyService {
  @Transactional
  public void performTransaction() {
  }
}
@Controller
public void MyController {
    private MyService service;
    private EurekaRegistration eurekaRegistration;
    
    @Autowired
    public MyControlle(MyService service, EurekaRegistration eurekaRegistration) {
        this.service = service;
        this.eurekaRegistration = eurekaRegistration;
    }
}

我刚刚注意到
AbstractIdleService
是一个类而不是一个接口,所以
MyService实现AbstractIdleService
不应该编译…我怀疑你没有展示所有内容,
startAsync()
不是非公共的(包私有的)就是
final
@Puce这是我的错,谢谢你指出这一点。我现在已经更改了。谢谢@M.Deinum,我将事件处理程序方法移到了控制器中以避免任何混乱。同样,您仍然没有显示所有内容。如前所述,
startAsync
可能是一种
final
方法或非公开方法。但是如果没有看到超类上实际的
startAsync
方法定义,就无法回答。我刚刚注意到
AbstractIdleService
是一个类而不是一个接口,因此
MyService实现了AbstractIdleService
不应该编译…我怀疑您没有显示所有内容,并且
startAsync()
是非公开(包私有)或
最终版
@Puce这是我的错,谢谢你指出。我现在已经更改了。谢谢@M.Deinum,我将事件处理程序方法移到了控制器中以避免任何混乱。同样,您仍然没有显示所有内容。如前所述,
startAsync
可能是一种
final
方法或非公开方法。但是如果看不到超类上的实际
startAsync
方法定义,就无法回答。感谢Puce,很抱歉回答得太晚,但是这个解决方案不起作用,我通过移动“事务性”解决了这个问题方法转换为另一个Spring组件类,并将该类自动连接到my MyService类,my MyService类现在只创建新类的cglib代理,而不是原始MyService类,该类允许MyService类扩展AbstractIdleService类并运行启动逻辑。感谢Puce,很抱歉回复晚了,但此解决方案不起作用,我通过移动“事务性”解决了此问题方法转换为另一个Spring组件类,并将该类自动连接到my MyService类中,my MyService类现在只创建新类的cglib代理,而不是原始MyService类,该类允许MyService类扩展AbstractIdleService类并运行启动逻辑。