请查看下面的更新。
我有一个Spring Boot应用程序,我可以在其中接受TCP / IP连接:
public MyClass implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
try (ServerSocket serverSocket = new ServerSocket(port)) {
while (true) {
Socket socket = serverSocket.accept();
new ServerThread(socket).start();
}
}
}
...
private class ServerThread extends Thread {
@Override
public void run() {
try (InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream()) {
// Read line from input and call a method from service:
service.myMethod(lineConvertedToMyObject);
} catch {
...
}
}
}
}
现在,它可以正常工作。但是,当我将AspectJ引入
myMethod
时:@Aspect
@Component
public class MyServiceAspect {
private static final Logger logger = LoggerFactory.getLogger(MyServiceAspect.class);
@Around(value = "execution(* com.package.to.MyService.myMethod(..))")
public MyObject rules(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
MyObject obj = (MyObject) joinPoint.proceed();
logger.debug("Took {} milliseconds", System.currentTimeMillis() - startTime);
return obj;
}
}
service.myMethod
不被调用,线程被阻塞。我想念什么?更新:
所以这是交易:
MyService
,MyServiceImpl
和MyServiceAspect
都在同一个包中。将MyServiceAspect
移至另一个软件包即可使其工作。这会给任何人敲响钟声吗?很高兴将赏金奖励给任何解释此行为的人。谢谢!
更新2:
另一个解决方案:再次在
@DependsOn(value = {"myServiceAspect"})
之上添加MyServiceImpl
可以解决此问题,但仍然想知道为什么。 最佳答案
实际问题
正如Alexander Paderin >>在他对afterPropertiesSet()
中相关的question >>无限循环的回答中所描述的那样,它是线程阻止程序,因为在这种情况下,控制权不会返回到Spring。
1.使用示例的示例(问题编辑后不实际)
您提供的代码示例不直接包含问题,AspectJ声明很好。
首先,请允许我分享工作示例:spring-aspectj-sockets。它基于Spring 5.1.0和AspectJ 1.9.1(当前最新版本),并且使用您的示例,而与MyServiceAspect
的位置/包无关。
2.问题说明
2.1。介绍
您的示例中最可能的线程阻止程序是对ServerSocket.accept()
的调用,此方法的javadocs说:
侦听与此套接字建立的连接并接受它。 该方法将阻塞直到建立连接。
有两种正确的方式处理accept()
:
serverSocket = new ServerSocket(18080);
clientSocket = new Socket("127.0.0.1", 18080); // initializing connection
Socket socket = serverSocket.accept(); // then calling accept()
serverSocket = new ServerSocket(18080);
serverSocket.setSoTimeout(5000); // 5 seconds timeout
Socket socket = serverSocket.accept(); // then calling accept()
注意:如果在5秒钟内没有连接,
accept()
将抛出异常,但不会阻塞线程2.2。假设条件
我假设您正在使用1-st方法,并且在某处有一行初始化连接的行,即
clientSocket = new Socket("127.0.0.1", 18080);
。但是它被调用(例如,如果使用静态声明):
serverSocket.accept()
与MyServiceAspect
之后MyServiceAspect
位于其他位置3.调试
我不确定是否需要这样做,由于悬赏的描述有疑问,让我快速介绍一下,以防万一。
您可以使用“远程调试”来调试应用程序-它涵盖了方面,子线程,服务等-您只需要: