Tendrá un aspecto se ejecutará de forma asíncrona si pongo método @Async en él?

Pasha:

Tengo mi ControllerLoggerclase que tiene algunos métodos con @Beforey @AfterReturninganotaciones.

Van a empezar a ser ejecutado de forma asíncrona si pongo @Asyncen cada uno de ellos, junto con @EnableAsync?

¿Cómo entonces pueden resolver y crear para los métodos de los proxies y serán?

kriegaex:

Lo que me llama la atención en primer lugar cuando la lectura de su pregunta es: ¿Por qué no acaba de tratar en lugar de hacer una pregunta aquí y esperar una respuesta? Después de un minuto que se sabe.

La segunda pregunta es: ¿Por qué quieres para crear una nueva tarea cada vez se está ejecutando el consejo de un aspecto? Habría que ser realmente más rápido que la ejecución sincrónica? Utilizando su nombre del aspecto ControllerLoggerllego a la conclusión de que lo único que hace que el registro. Pero de todos modos, tal vez su registro es tan lento que realmente tiene sentido para que sea asíncrono. Por lo general, se puede configurar que para su marco de registro ya, así que no necesitaría el aspecto a cuidar de él.

Finalmente la respuesta a su pregunta: nunca he intentado que antes de mí mismo, pero me tomó dos minutos para la prueba:

  • Añadir una declaración como System.out.println(Thread.currentThread() + " -> " + Thread.currentThread().getId());tanto a su consejo de aspecto y un método de destino.
  • Sin correr @Async/ @EnableAsync. Tenga en cuenta los resultados.
  • Correr de nuevo con @Async/ @EnableAsync. Tenga en cuenta los resultados.

Para mí, vi algo como esto antes:

Thread[main,5,main] -> 1
Thread[main,5,main] -> 1
Thread[main,5,main] -> 1
Thread[main,5,main] -> 1

Y esto después de activar la ejecución asíncrona (3 consejos de aspecto ejecutado):

Thread[main,5,main] -> 1
Thread[SimpleAsyncTaskExecutor-1,5,main] -> 18
Thread[SimpleAsyncTaskExecutor-2,5,main] -> 25
Thread[SimpleAsyncTaskExecutor-3,5,main] -> 26

Así que la respuesta es: Sí, consejos de aspecto como @Beforeo @Afterpara la primavera AOP se ejecutarán de forma asíncrona.

Tenga cuidado con los @Aroundconsejos, sin embargo, porque si los métodos de destino (y por tanto también el asesoramiento en torno a) devuelve un tipo distinto voido Future(como se documenta en el @AsyncJavadoc de anotación ), obtendrá excepciones de tiempo de ejecución porque el consejo de forma asíncrona ejecutado volverá nulla la interceptado método primero. Por lo que se vería una excepción de esta manera:

Exception in thread "main" 
org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public int spring.aop.MyController.doSomething(java.lang.String,int)
    at org.springframework.aop.framework.CglibAopProxy.processReturnType(CglibAopProxy.java:362)
    at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:84)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:658)
    at spring.aop.MyController$$EnhancerBySpringCGLIB$$c28d13a5.doSomething(<generated>)
    at spring.aop.DemoApplication.main(DemoApplication.java:28)

Así que asegúrese de usar @Async+ @Aroundsólo en casos en los que la ejecución asíncrona realmente tiene sentido y para el cual se diseñó la anotación.


Actualización: La excepción anterior sólo aparecerá para los métodos que retornan tipos primitivos, por ejemplo, si sus devuelve el método una inty un asesoramiento alrededor se ejecuta y llamando JoinPoint.proceed(). Si el mismo método que volvería Integeren su lugar, el asesoramiento en torno ejecutaría sin un error, pero volver null, que es algo que su interlocutor no espera y potencialmente podría romper su programa. Así que como he dicho, tenga cuidado de cómo utilizar esto con @Around.


Actualización 2: Incluso si el método devuelve un objetivo Future, pero los rendimientos de asesoramiento en torno a algo distinto, por ejemplo Object, proceed()va a volver null. Sólo si se hace el consejo alrededor también tienen un tipo de retorno de Future, lo que realmente funciona y la persona que llama puede manejar el futuro como se esperaba y después de esperar isDone()en realidad recibe el resultado esperado.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=315933&siteId=1
Recomendado
Clasificación