[JAVA] Stimmt die Anmerkungen auf der Schnittstelle mit Spring AOP überein


Problem

In Spring AOP (AspectJ) können Punktschnitte, bei denen die an die Schnittstelle angehängte Anmerkung als Markierung verwendet wird, nicht verwendet werden. Daher ist es nicht möglich, einen Interceptor als Anmerkungszeichen in die Methode der Mapper-Schnittstelle von MyBatis einzufügen.

Ursache

Die an die Methode angehängte Anmerkung wird nicht von der Methode der geerbten Klasse (oder der Klasse, die die Schnittstelle implementiert) geerbt. Und da Spring AOP (oder AspectJ) auf instanziierte Beans abzielt, deren Typ die Klasse ist, die die Schnittstelle implementiert, werden die an die Methoden der Schnittstelle angehängten Anmerkungen nicht überprüft.

Lösungen

Die an die Benutzeroberfläche angehängte Anmerkung wird auch verwendet, indem "AspectJPointcutAdvisor" so angepasst wird, dass sie zum Zeitpunkt der Pointcut-Beurteilung überprüft wird.

Erweiterung von AspectJPointcutAdvisor

Da es eine Methode gibt, um den Punktschnitt zu erhalten, überschreiben Sie diese und überprüfen Sie auch die Schnittstellenanmerkungen.

InterfaceMethodAwareAspectJPointcutAdvisor.java


package aop;

import java.lang.reflect.Method;
import java.util.stream.Stream;

import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.aspectj.AbstractAspectJAdvice;
import org.springframework.aop.aspectj.AspectJPointcutAdvisor;
import org.springframework.aop.support.ComposablePointcut;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;

public class InterfaceMethodAwareAspectJPointcutAdvisor extends AspectJPointcutAdvisor {
    public InterfaceMethodAwareAspectJPointcutAdvisor(@NonNull AbstractAspectJAdvice advice) {
        super(advice);
    }

    @Override
    public Pointcut getPointcut() {
        val original = super.getPointcut();
        return new ComposablePointcut(original)
                .union(new InterfaceAwareMethodMatcher(original.getMethodMatcher()));
    }

    @RequiredArgsConstructor
    private static class InterfaceAwareMethodMatcher implements MethodMatcher {
        @NonNull
        private final MethodMatcher underlying;

        @Override
        public boolean isRuntime() {
            return underlying.isRuntime();
        }

        @Override
        public boolean matches(Method method, Class<?> targetClass) {
            return Stream.of(targetClass.getInterfaces())
                         .anyMatch(x -> underlying.matches(method, x));
        }

        @Override
        public boolean matches(Method method, Class<?> targetClass, Object... args) {
            return Stream.of(targetClass.getInterfaces())
                         .anyMatch(x -> underlying.matches(method, x, args));
        }
    }
}

Konfigurationsklasse

Registrieren Sie den Advisor mit dem "InterfaceMethodAwareAspectJPointcutAdvisor", der auch die oben erstellten Schnittstellenanmerkungen überprüft.

AspectConfiguration.java


@Configuration
@EnableAspectJAutoProxy
public class AspectConfiguraiton implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(@NonNull ConfigurableListableBeanFactory factory) {
    	val original = new FooAspect();
    	val advisor = new ReflectiveAspectJAdvisorFactory()
    	        .getAdvisors(new SingletonMetadataAwareAspectInstanceFactory(original, "fooAspect"));
    	        
    	 advisors.stream()
    	         .map(advisor -> new InterfaceMethodAwareAspectJPointcutAdivsor((AbstractAspectJAdvice) advisor))
    	         .forEacth(advisor -> factory.registerSingleton(resolveName(advisor), advisor));

    }
    
    private static String resolveName(AspectJPointcutAdvisor advisor) {
        val info = (AspectJPrecedenceInformation) advisor.getAdvice();
        return info.getAspectName() + '#' + info.getDeclarationOrder();
    }
}

Recommended Posts

Stimmt die Anmerkungen auf der Schnittstelle mit Spring AOP überein
gRPC auf Spring Boot mit grpc-spring-boot-Starter
Programmieren mit Ruby (unterwegs)
Spring AOP zum ersten Mal
Verwenden Sie Vorlagen für den Klassenpfad mit Apache Velocity
Geben Sie ein Suffix für die Methode an
Veröffentlichen Sie die mit Ruby on Rails erstellte App
Geben Sie ein Suffix für Methode 2 heraus
Bestimmen Sie die aktuelle Seite mit Ruby on Rails
Über Spring AOP
Über den Frühling AOP
Nutzen Sie Spring AOP + Cyclic Barrier, um optimistische Verriegelungstestbedingungen in der Spring Boot-App sicherzustellen
Refactor die Implementierung des Decorator-Musters mit einer funktionalen Schnittstelle
Feder mit Kotorin ―― 3. Auslassen von Wellenklammern aus der Funktion
Greifen Sie mit jdbcTemplate auf das integrierte h2db des Spring Boot zu
Zeigen Sie die Liste in setDetails mit Federsicherheit auf dem Bildschirm an
Eine Übersicht über die Spring Framework Resource-Oberfläche
Stellen Sie das Spring Boot-Projekt in XAMPP für Tomcat bereit
Steuern Sie den Spring Batch-Verarbeitungsablauf mit JavaConfig.