[JAVA] Eine Geschichte über eine BeanNotOfRequiredTypeException, die nach der Anwendung von AOP im Frühjahr aufgetreten ist

Betriebsumgebung

Wie die Ausnahme aufgetreten ist

Der Code, der die Ausnahme tatsächlich verursacht hat, kann nicht veröffentlicht werden. Nehmen wir also die in den TERASOLUNA-Richtlinien eingeführte Todo-Anwendung als Beispiel: Schweiß :.

--Erstellen Sie eine Klasse, die "MethodInterceptor" unter dem Domänenpaket implementiert.

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 {
    //Melden Sie sich einfach ab, bevor Sie die Zielmethode ausführen
    logger.info("Interceptor called.");
    return invocation.proceed();
  }
}

--Wenden Sie den in ↑ erstellten Interceptor auf den TodoServiceImpl in den AOP-Einstellungen in todo-domain.xml an.

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)" />← Das Original
    <aop:advisor pointcut-ref="sample" advice-ref="sampleAdvice" order="-1" />
  </aop:config>

  <bean id="sampleAdvice" class="todo.domain.interceptor.SampleInterceptor" />

TodoController.java


@Controller
@RequestMapping("todo")
public class TodoController {
  @Inject
  TodoServiceImpl todoService;

Wenn ich diese Todo-Anwendung ausführe, wird beim Start die folgende Ausnahme angezeigt.

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

Ich gehe vom Typ "TodoServiceImpl" aus, aber es scheint, dass er tatsächlich als "com.sun.proxy" definiert ist. $ Proxy32 "Typ: schreien :.

Der Grund ist der Unterschied im Mechanismus zum Erstellen von Proxy

Spring bietet zwei Mechanismen zum Anwenden von AOP.

  1. JDK DynamicProxy
  2. CGLib

Dieser Unterschied ergibt sich aus Grundlegendes zur Implementierung der allgemeinen Anforderungsverarbeitung in Spring MVC (+ Spring Boot). Es scheint, dass Sie eine Schnittstelle implementieren. In diesem Beispiel wurde die Schnittstelle, da sie implementiert ist, mit "JDK DynamicProxy" in "Proxy" konvertiert. Es scheint jedoch eine Ausnahme aufgetreten zu sein, weil "TodoContorller" versucht hat, die Implementierungsklasse "TodoServiceImpl" zu "injizieren". .. In diesem Fall ist es zum "Injizieren" der Implementierungsklasse erforderlich, sie unter Verwendung des CGLib-Mechanismus zum Proxy zu machen, und die Einstellung besteht darin, das Attribut "Proxy-Zielklasse" des "config" -Elements von AOP auf "true" zu setzen. Ich werde. (Der Standardwert ist "false".)

todo-domain.xml


 <aop:config proxy-target-class="true">

Die obigen Einstellungen erzwingen, dass der Proxy-Konvertierungsmechanismus CGLib ist. Wenn die Klasse ursprünglich keine Schnittstelle hat, wird sie vom CGLib-Mechanismus automatisch in Proxy konvertiert.

Beachten Sie übrigens, dass Spring AOP nicht für Klassen gilt, die nicht im DI-Container ** registriert sind.

Wie bist du dazu gekommen, diesen Artikel zu posten?

Als Hinweis, weil es tatsächlich in dem im Geschäft entwickelten System aufgetreten ist: stecken_out_tongue :.

Andere Referenzartikel / -seiten

Recommended Posts

Eine Geschichte über eine BeanNotOfRequiredTypeException, die nach der Anwendung von AOP im Frühjahr aufgetreten ist
Über Spring AOP
Über den Frühling AOP
Eine Geschichte über ein in Java geschriebenes Spring Boot-Projekt, das Kotlin unterstützt
Eine Geschichte über das JDK in der Java 11-Ära
Über Spring AOP Pointcut
Eine Geschichte darüber, wie Spring + Hibernate + MySQL-Apps die Replikation unterstützen
Über das Binden der Spring AOP Annotation
Eine kleine unruhige Geschichte mit Groovy
Erstellen Sie mit Intellij ein Spring Boot-Projekt und beenden Sie es sofort nach dem Start
Eine Geschichte über das Konvertieren von Zeichencodes von UTF-8 in Shift-jis in Ruby
Die Geschichte eines arithmetischen Überlaufs, der in Ruby nicht auftreten sollte
Informationen zum Zurückgeben einer Referenz in einem Java Getter
[Erstellen] Ein Memorandum über das Codieren in Java
Eine Geschichte über einen Super-Anfänger, der zum ersten Mal am AtCoder-Wettbewerb teilnimmt (AtCoder-Anfängerwettbewerb 140)