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:.