天天看點

配置AOP時擷取被代理的類上的注解會導緻擷取失敗

項目場景

在使用AOP時,會使用動态代理,如果此時再擷取被代理的類上的注解會導緻擷取失敗。

問題描述

配置AOP掃描所有的service

@Pointcut("within(com.ddwl..*.service..*)")
public void serviceAspect() {}
    
@Before("serviceAspect()")
public void before(JoinPoint joinPoint) throws TransactionException {
       
}
           

在項目啟動時發現如下錯誤

[ERROR][2022-12-08 17:17:36.378] org.springframework.boot.SpringApplication [830] - Application run failed
java.lang.IllegalStateException: Failed to register @ServerEndpoint class: class com.ddwl.message.service.WsAuthService$$EnhancerBySpringCGLIB$$77e25c55
	at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.java:159)
	at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoints(ServerEndpointExporter.java:134)
	at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterSingletonsInstantiated(ServerEndpointExporter.java:112)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:972)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
	at com.ddwl.message.MessageApplication.main(MessageApplication.java:29)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: javax.websocket.DeploymentException: Cannot deploy POJO class [com.ddwl.message.service.WsAuthService$$EnhancerBySpringCGLIB$$77e25c55] as it is not annotated with @ServerEndpoint
	at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:246)
	at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:229)
	at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.java:156)
	... 15 common frames omitted
           

通過報錯分析是@ServerEndpoint的原因 發現項目中确實引用webSocket

@ServerEndpoint("/ws/auth/{sessionId}")
@Component
public class WsAuthService {}
           

問題解決

AOP切點表達式配置不掃描@ServerEndpoint的service

@Pointcut("within(com.ddwl..*.service..*)")
public void serviceAspect() {}

@Before("serviceAspect() && [email protected](javax.websocket.server.ServerEndpoint)")
//@Before("serviceAspect()")
public void before(JoinPoint joinPoint) throws TransactionException {}