Le code à l'origine de l'exception ne peut pas être publié, prenons donc à titre d'exemple l'application Todo introduite dans les directives TERASOLUNA: sweat:.
--Créez une classe qui implémente MethodInterceptor sous le package de domaine.
SampleInterceptor.java
package todo.domain.interceptor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SampleInterceptor implements MethodInterceptor {
private static final Logger logger = LoggerFactory.getLogger(SampleInterceptor.class);
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
//Déconnectez-vous simplement avant d'exécuter la méthode cible
logger.info("Interceptor called.");
return invocation.proceed();
}
}
--Appliquer ʻInterceptorcréé dans ↑ àTodoServiceImpl` dans le paramètre AOP dans todo-domain.xml.
todo-domain.xml
<aop:config>
<aop:pointcut id="sample" expression="execution(* todo.domain.service.todo.TodoServiceImpl.*(..))" />
<aop:advisor advice-ref="resultMessagesLoggingInterceptor" pointcut="@within(org.springframework.stereotype.Service)" />← L'original
<aop:advisor pointcut-ref="sample" advice-ref="sampleAdvice" order="-1" />
</aop:config>
<bean id="sampleAdvice" class="todo.domain.interceptor.SampleInterceptor" />
Service qui est ʻInject dans TodoCotroller en TodoServiceImpl`.TodoController.java
@Controller
@RequestMapping("todo")
public class TodoController {
@Inject
TodoServiceImpl todoService;
Ainsi, lorsque j'exécute cette application Todo, j'obtiens l'exception suivante au démarrage.
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'todoServiceImpl' is expected to be of type 'todo.domain.service.todo.TodoServiceImpl' but was actually of type 'com.sun.proxy.$Proxy32'
at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1491)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1498)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1470)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102):rolling_eyes:
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 42 more
Je suppose le type TodoServiceImpl, mais il semble qu'il soit en fait défini comme com.sun.proxy. $ Proxy32 type: scream:.
Spring fournit deux mécanismes pour appliquer l'AOP.
Cette différence est due à Comprendre comment implémenter le traitement des requêtes courantes sur Spring MVC (+ Spring Boot). Il semble que vous implémentez une interface.
Dans cet exemple, étant donné que l'interface est implémentée, elle a été convertie en Proxy en utilisant JDK DynamicProxy, mais il semble qu'une exception se soit produite parce que TodoContorller a essayé d'injecter la classe d'implémentation TodoServiceImpl. ..
Dans ce cas, pour «injecter» la classe d'implémentation, il est nécessaire de la rendre Proxy en utilisant le mécanisme de CGLib, et le réglage est de définir l'attribut «proxy-target-class» de l'élément «config» d'AOP sur «true». Je vais.
(La valeur par défaut est «false».)
todo-domain.xml
<aop:config proxy-target-class="true">
Le paramètre ci-dessus force le mécanisme de conversion Proxy à être CGLib, et si la classe n'a pas à l'origine une interface, elle sera automatiquement convertie en Proxy par le mécanisme CGLib.
À propos, veuillez noter que Spring AOP ne s'applique pas aux classes qui ne sont pas enregistrées dans le conteneur DI **.
A noter car il s'est effectivement produit dans le système développé en entreprise: stuck_out_tongue:.