Spring boot Springboot@Transactional-如何在创建服务代理时使spring调用超级化?
我在Springboot方面有中级技能,可以开发简单到中等复杂的应用程序,但这一点让我有点扫兴 我有一个@Service扩展了Guava的AbstractIdleService,还有一个@Controller自动连接了该服务的实例 在服务中,我有一个方法,比如performTransaction(),它用@Transactional注释(当然是让Spring处理事务),它确实创建了服务类的代理。但是当我调试应用程序时,我可以看到注入控制器中的代理包含所有super class(AbstractIdleService)类字段,因为null表示在创建服务的代理时不会调用super()。因此,在调用超类(AbstractIdleService)的startAsync方法时,应用程序无法初始化。我真的不知道该怎么做 我在下面添加了一些代码以进行说明。 这是我的服务课:Spring boot Springboot@Transactional-如何在创建服务代理时使spring调用超级化?,spring-boot,transactions,cglib,Spring Boot,Transactions,Cglib,我在Springboot方面有中级技能,可以开发简单到中等复杂的应用程序,但这一点让我有点扫兴 我有一个@Service扩展了Guava的AbstractIdleService,还有一个@Controller自动连接了该服务的实例 在服务中,我有一个方法,比如performTransaction(),它用@Transactional注释(当然是让Spring处理事务),它确实创建了服务类的代理。但是当我调试应用程序时,我可以看到注入控制器中的代理包含所有super class(AbstractI
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类并运行启动逻辑。