Inhaltsverzeichnis
Spring implementiert benutzerdefinierte Anmerkungen
1. Einführung verwandter Abhängigkeiten
Es gibt einige Meta-Anmerkungen im JDK, hauptsächlich @Target, @Retention, @Document und @Inherited, die zum Ändern von Anmerkungen verwendet werden. Das Folgende ist eine benutzerdefinierte Anmerkung.
Betriebseffekt:
Der dynamische Java-Proxy verwendet den Reflexionsmechanismus, um eine anonyme Klasse zu generieren, die die Proxy-Schnittstelle implementiert, und ruft sie auf bevor Sie die spezifische Methode InvokeHandler aufrufen, die verarbeitet werden soll.
Der dynamische Proxy von cglib verwendet das Open-Source-Paket ASM, um die Klassendatei der Proxy-Objektklasse zu laden und durch Ändern ihres Bytecodes zu verarbeiten, um eine Unterklasse zu generieren.
Heim Java javaLernprogramm So verwenden Sie AOP und Interceptors, um benutzerdefinierte Anmerkungen in SpringBoot zu implementieren

So verwenden Sie AOP und Interceptors, um benutzerdefinierte Anmerkungen in SpringBoot zu implementieren

May 29, 2023 pm 07:58 PM
aop springboot

    Spring implementiert benutzerdefinierte Anmerkungen

    Implementierung benutzerdefinierter Anmerkungen über Interceptor + AOP, wobei der Interceptor als Methode fungiert, die bei der angegebenen Annotation ausgeführt werden soll, und Aop dafür verantwortlich ist, die Methode des Interceptors und die Annotation in Kraft zu setzen Ein Weben vor Ort (Proxy-Klassenimplementierung durch dynamische Annotation generieren).

    1. Einführung verwandter Abhängigkeiten

    spring-boot-starter: einige grundlegende Abhängigkeiten von Spring

    spring-boot-starter-aop: einige verwandte Abhängigkeiten von Spring, die Aop implementieren

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
    Nach dem Login kopieren

    1. Benutzerdefinierte Annotationsklasse

    @Target({ElementType.TYPE})  //说明了Annotation所修饰的对象范围,这里,的作用范围是类、接口(包括注解类型) 或enum
    @Retention(RetentionPolicy.RUNTIME)  //自定义注解的有效期,Runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
    @Documented //标注生成javadoc的时候是否会被记录
    public @interface EasyExceptionResult {
    }
    Nach dem Login kopieren
    Nach dem Login kopieren

    2. Interceptor-Klasse

    /**
     * MethodInterceptor是AOP项目中的拦截器(注:不是动态代理拦截器),
     * 区别与HandlerInterceptor拦截目标时请求,它拦截的目标是方法。
     */
    public class EasyExceptionIntercepter implements MethodInterceptor {
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            AnnotatedElement element=invocation.getThis().getClass();
            EasyExceptionResult easyExceptionResult=element.getAnnotation(EasyExceptionResult.class);
            if (easyExceptionResult == null) {
                return invocation.proceed();
            }
            try {
                return invocation.proceed();
            } catch (Exception rpcException) {
                //不同环境下的一个异常处理
                System.out.println("发生异常了");
                return null;
            }
        }
    }
    Nach dem Login kopieren

    3. Die Implementierungsklasse von MethodInterceptor kann als Ausführungsmethode von Aspector verwendet werden, da die übergeordnete Klasse von Interceptor Advice ist.

    @Configuration
    public class EasyExceptionAdvisor {
     
        /**
         * 放在最后执行
         * 等待ump/日志等记录结束
         *
         * @return {@link DefaultPointcutAdvisor}对象
         */
        @Bean
        @Order(Integer.MIN_VALUE)
        public DefaultPointcutAdvisor easyExceptionResultAdvisor() {
            DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
            //针对EasyExceptionResult注解创建切点
            AnnotationMatchingPointcut annotationMatchingPointcut = new AnnotationMatchingPointcut(EasyExceptionResult.class, true);
            EasyExceptionIntercepter interceptor = new EasyExceptionIntercepter();
            advisor.setPointcut(annotationMatchingPointcut);
            //在切点执行interceptor中的invoke方法
            advisor.setAdvice(interceptor);
            return advisor;
        }
     
    }
    Nach dem Login kopieren

    4. Verwendung von benutzerdefinierten Anmerkungen

    @Service
    @EasyExceptionResult  //自定义异常捕获注解
    public class EasyServiceImpl {
     
        public void testEasyResult(){
            throw new NullPointerException("测试自定义注解");
        }
     
    }
    Nach dem Login kopieren

    5. Wirkung

    @SpringBootApplication
    public class JdStudyApplication {
     
        public static void main(String[] args) {
            ConfigurableApplicationContext context=SpringApplication.run(JdStudyApplication.class, args);
            EasyServiceImpl easyService=context.getBean(EasyServiceImpl.class);
            easyService.testEasyResult();
        }
     
    }
    Nach dem Login kopieren

    Bisher wurden benutzerdefinierte Anmerkungen bis zum Frühjahr implementiert.

    So verwenden Sie AOP und Interceptors, um benutzerdefinierte Anmerkungen in SpringBoot zu implementierenJava implementiert benutzerdefinierte Anmerkungen

    Obwohl benutzerdefinierte Anmerkungen über Spring implementiert werden, gibt es für uns immer noch Möglichkeiten, benutzerdefinierte Anmerkungen zu implementieren, ohne Spring zu verwenden. Schließlich gibt es Anmerkungen früher als Spring.

    Es gibt einige Meta-Anmerkungen im JDK, hauptsächlich @Target, @Retention, @Document und @Inherited, die zum Ändern von Anmerkungen verwendet werden. Das Folgende ist eine benutzerdefinierte Anmerkung.

    @Target({ElementType.TYPE})  //说明了Annotation所修饰的对象范围,这里,的作用范围是类、接口(包括注解类型) 或enum
    @Retention(RetentionPolicy.RUNTIME)  //自定义注解的有效期,Runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
    @Documented //标注生成javadoc的时候是否会被记录
    public @interface EasyExceptionResult {
    }
    Nach dem Login kopieren
    Nach dem Login kopieren

    @Target

    Gibt den Java-Elementtyp an, auf den diese Annotation angewendet werden kann

    ZieltypBeschreibungGilt für Klassen, Schnittstellen (einschließlich Anmerkungstypen) und Aufzählungen angewandt auf Eigenschaften (einschließlich Konstanten in Aufzählungen) angewandt auf Methoden angewandt auf. Methode Parameterwird auf Konstruktoren angewendetwird auf lokale Variablen angewendetwird auf Annotationstypen angewendetauf die Tasche aufgetragenNeu in Version 1.8, angewendet auf Typvariablen) Neu in Version 1.8, angewendet auf alle Anweisungen, die Typen verwenden (z. B. Deklarationsanweisungen, Generika und Umwandlungsanweisungen). Geben Sie ein )@Retention
    ElementType.TYPE
    ElementType.FIELD
    ElementType.METHOD
    ElementType.PARAMETER
    ElementType.CONSTRUCTOR
    ElementType.LOCAL_VARIABLE
    ElementType.ANNOTATION_TYPE
    ElementType.PACK AGE
    ElementType.TYPE_PARAMETER
    ElementType.TYPE_USE

    Gibt den Lebenszyklus der Anmerkung an

    LebenszyklustypBeschreibung wird verworfen Kompilieren, nicht in der Klasse enthalten Die Datei wird beim Laden der JVM verworfen und in die Klassendatei aufgenommen. Der Standardwert wird von der JVM geladen und in die Klassendatei aufgenommen und kann sein Zur Laufzeit erhalten. An @Document
    RetentionPolicy.SOURCE
    RetentionPolicy.CLASS
    RetentionPolicy.RUNTIME

    gibt an, dass das durch diese Annotation markierte Element von Javadoc oder ähnlichen Tools dokumentiert werden kann

    @Inherited

    gibt an, dass die Annotation mit der Annotation @Inherited eine ist Unterklasse der markierten Klasse Die Klasse wird auch über diese Annotationimplementiert durch Cglib

    Nachdem wir die Annotation definiert haben, müssen wir überlegen, wie wir die Annotation und die Klasse miteinander verbinden, um den gewünschten Effekt zur Laufzeit zu erzielen Wir können den dynamischen Proxy-Mechanismus einführen. Die Annotation möchte die Operation ausführen, bevor die Methode ausgeführt wird, und eine Weboperation wird wie folgt ausgeführt, wenn die Klasse kompiliert wird.

    public static void main(String[] args) {
            Class easyServiceImplClass=EasyServiceImpl.class;
            //判断该对象是否有我们自定义的@EasyExceptionResult注解
            if(easyServiceImplClass.isAnnotationPresent(EasyExceptionResult.class)){
                final EasyServiceImpl easyService=new EasyServiceImpl();
                //cglib的字节码加强器
                Enhancer enhancer=new Enhancer();
                将目标对象所在的类作为Enhaner类的父类
                enhancer.setSuperclass(EasyServiceImpl.class);
                通过实现MethodInterceptor实现方法回调,MethodInterceptor继承了Callback
                enhancer.setCallback(new MethodInterceptor() {
                    @Override
                    public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        try{
                            method.invoke(easyService, args);
                            System.out.println("事务结束...");
                        }catch (Exception e){
                            System.out.println("发生异常了");
                        }
                        return proxy;
                    }
                });
     
                Object obj= enhancer.create();;
                EasyServiceImpl easyServiceProxy=(EasyServiceImpl)obj;
                easyServiceProxy.testEasyResult();
            }
     
        }
    Nach dem Login kopieren

    Betriebseffekt:

    implementiert durch den dynamischen JDk-Proxy

    public class EasyServiceImplProxy implements InvocationHandler {
     
        private EasyServiceImpl target;
     
        public void setTarget(EasyServiceImpl target)
        {
            this.target = target;
        }
     
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 这里可以做增强
            System.out.println("已经是代理类啦");
            try{
                return  method.invoke(proxy, args);
            }catch (Exception e){
                System.out.println("发生异常了");
                return null;
            }
        }
     
     
        /**
         * 生成代理类
         * @return 代理类
         */
        public Object CreatProxyedObj()
        {
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
    }
    Nach dem Login kopieren
    So verwenden Sie AOP und Interceptors, um benutzerdefinierte Anmerkungen in SpringBoot zu implementierenDer Unterschied zwischen Cglib und dem dynamischen JDK-Proxy

    Der dynamische Java-Proxy verwendet den Reflexionsmechanismus, um eine anonyme Klasse zu generieren, die die Proxy-Schnittstelle implementiert, und ruft sie auf bevor Sie die spezifische Methode InvokeHandler aufrufen, die verarbeitet werden soll.

    Der dynamische Proxy von cglib verwendet das Open-Source-Paket ASM, um die Klassendatei der Proxy-Objektklasse zu laden und durch Ändern ihres Bytecodes zu verarbeiten, um eine Unterklasse zu generieren.

    1. Wenn das Zielobjekt die Schnittstelle implementiert, wird standardmäßig der dynamische Proxy von JDK verwendet, um AOP zu implementieren.

    2 Wenn das Zielobjekt die Schnittstelle implementiert, können Sie die Verwendung von CGLIB erzwingen

    3. Wenn das Zielobjekt die Schnittstelle nicht implementiert, muss die CGLIB-Bibliothek verwendet werden. Spring führt automatisch eine Konvertierung zwischen dem dynamischen JDK-Proxy und CGLIB durch.

    Wie erzwinge ich die Verwendung von CGLIB zur Implementierung von AOP?

    (1) Fügen Sie die CGLIB-Bibliothek SPRING_HOME/cglib/*.jar hinzu. (2) Fügen Sie

    in der Spring-Konfiguration hinzu Datei Was ist der Unterschied zwischen dem dynamischen JDK-Proxy und der CGLIB-Bytecode-Generierung?

    (1) Der dynamische JDK-Proxy kann nur Proxys für Klassen generieren, die Schnittstellen implementieren, nicht jedoch für Klassen.

    (2) CGLIB implementiert Proxys für Klassen, hauptsächlich um eine Unterklasse für die angegebene Klasse zu generieren und diese abzudecken Methode

    Weil Da es vererbt wird, ist es am besten, die Klasse oder Methode nicht als final zu deklarieren

    Das obige ist der detaillierte Inhalt vonSo verwenden Sie AOP und Interceptors, um benutzerdefinierte Anmerkungen in SpringBoot zu implementieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

    Heiße KI -Werkzeuge

    Undresser.AI Undress

    Undresser.AI Undress

    KI-gestützte App zum Erstellen realistischer Aktfotos

    AI Clothes Remover

    AI Clothes Remover

    Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

    Undress AI Tool

    Undress AI Tool

    Ausziehbilder kostenlos

    Clothoff.io

    Clothoff.io

    KI-Kleiderentferner

    AI Hentai Generator

    AI Hentai Generator

    Erstellen Sie kostenlos Ai Hentai.

    Heißer Artikel

    R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Beste grafische Einstellungen
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25: Wie man alles in Myrise freischaltet
    1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

    Heiße Werkzeuge

    Notepad++7.3.1

    Notepad++7.3.1

    Einfach zu bedienender und kostenloser Code-Editor

    SublimeText3 chinesische Version

    SublimeText3 chinesische Version

    Chinesische Version, sehr einfach zu bedienen

    Senden Sie Studio 13.0.1

    Senden Sie Studio 13.0.1

    Leistungsstarke integrierte PHP-Entwicklungsumgebung

    Dreamweaver CS6

    Dreamweaver CS6

    Visuelle Webentwicklungstools

    SublimeText3 Mac-Version

    SublimeText3 Mac-Version

    Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

    Wie Springboot Jasypt integriert, um die Verschlüsselung von Konfigurationsdateien zu implementieren Wie Springboot Jasypt integriert, um die Verschlüsselung von Konfigurationsdateien zu implementieren Jun 01, 2023 am 08:55 AM

    Einführung in Jasypt Jasypt ist eine Java-Bibliothek, die es einem Entwickler ermöglicht, seinem Projekt mit minimalem Aufwand grundlegende Verschlüsselungsfunktionen hinzuzufügen und kein tiefes Verständnis der Funktionsweise der Verschlüsselung erfordert. standardbasierte Verschlüsselungstechnologie. Passwörter, Text, Zahlen, Binärdateien verschlüsseln ... Geeignet für die Integration in Spring-basierte Anwendungen, offene API, zur Verwendung mit jedem JCE-Anbieter ... Fügen Sie die folgende Abhängigkeit hinzu: com.github.ulisesbocchiojasypt-spring-boot-starter2 Die Vorteile von Jasypt schützen unsere Systemsicherheit. Selbst wenn der Code durchgesickert ist, kann die Datenquelle garantiert werden.

    Wie SpringBoot Redisson integriert, um eine Verzögerungswarteschlange zu implementieren Wie SpringBoot Redisson integriert, um eine Verzögerungswarteschlange zu implementieren May 30, 2023 pm 02:40 PM

    Nutzungsszenario 1. Die Bestellung wurde erfolgreich aufgegeben, die Zahlung erfolgte jedoch nicht innerhalb von 30 Minuten. Die Zahlung ist abgelaufen und die Bestellung wurde automatisch storniert. 2. Die Bestellung wurde unterzeichnet und es wurde 7 Tage lang keine Bewertung durchgeführt. Wenn die Bestellung abläuft und nicht ausgewertet wird, wird die Bestellung standardmäßig positiv bewertet. Wenn der Händler die Bestellung innerhalb von 5 Minuten nicht erhält, wird die Bestellung abgebrochen Es wird eine SMS-Erinnerung gesendet ... Für Szenarien mit langen Verzögerungen und geringer Echtzeitleistung können wir die Aufgabenplanung verwenden, um eine regelmäßige Abfrageverarbeitung durchzuführen. Zum Beispiel: xxl-job Heute werden wir auswählen

    So implementieren Sie verteilte Sperren mit Redis in SpringBoot So implementieren Sie verteilte Sperren mit Redis in SpringBoot Jun 03, 2023 am 08:16 AM

    1. Redis implementiert das Prinzip der verteilten Sperren und warum verteilte Sperren erforderlich sind. Bevor über verteilte Sperren gesprochen wird, muss erläutert werden, warum verteilte Sperren erforderlich sind. Das Gegenteil von verteilten Sperren sind eigenständige Sperren. Wenn wir Multithread-Programme schreiben, vermeiden wir Datenprobleme, die durch den gleichzeitigen Betrieb einer gemeinsam genutzten Variablen verursacht werden. Normalerweise verwenden wir eine Sperre, um die Richtigkeit der gemeinsam genutzten Variablen sicherzustellen Die gemeinsam genutzten Variablen liegen im gleichen Prozess. Wenn es mehrere Prozesse gibt, die gleichzeitig eine gemeinsam genutzte Ressource betreiben müssen, wie können sie sich dann gegenseitig ausschließen? Heutige Geschäftsanwendungen sind in der Regel Microservice-Architekturen, was auch bedeutet, dass eine Anwendung mehrere Prozesse bereitstellen muss. Wenn mehrere Prozesse dieselbe Datensatzzeile in MySQL ändern müssen, ist eine Verteilung erforderlich, um fehlerhafte Daten zu vermeiden wird zu diesem Zeitpunkt eingeführt. Der Stil ist gesperrt. Punkte erreichen wollen

    So lösen Sie das Problem, dass Springboot nach dem Einlesen in ein JAR-Paket nicht auf die Datei zugreifen kann So lösen Sie das Problem, dass Springboot nach dem Einlesen in ein JAR-Paket nicht auf die Datei zugreifen kann Jun 03, 2023 pm 04:38 PM

    Springboot liest die Datei, kann aber nach dem Packen in ein JAR-Paket nicht auf die neueste Entwicklung zugreifen. Es gibt eine Situation, in der Springboot die Datei nach dem Packen in ein JAR-Paket nicht lesen kann ist ungültig und kann nur über den Stream gelesen werden. Die Datei befindet sich unter resources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input

    So implementieren Sie Springboot+Mybatis-plus, ohne SQL-Anweisungen zum Hinzufügen mehrerer Tabellen zu verwenden So implementieren Sie Springboot+Mybatis-plus, ohne SQL-Anweisungen zum Hinzufügen mehrerer Tabellen zu verwenden Jun 02, 2023 am 11:07 AM

    Wenn Springboot + Mybatis-plus keine SQL-Anweisungen zum Hinzufügen mehrerer Tabellen verwendet, werden die Probleme, auf die ich gestoßen bin, durch die Simulation des Denkens in der Testumgebung zerlegt: Erstellen Sie ein BrandDTO-Objekt mit Parametern, um die Übergabe von Parametern an den Hintergrund zu simulieren dass es äußerst schwierig ist, Multi-Table-Operationen in Mybatis-plus durchzuführen. Wenn Sie keine Tools wie Mybatis-plus-join verwenden, können Sie nur die entsprechende Mapper.xml-Datei konfigurieren und die stinkende und lange ResultMap konfigurieren Schreiben Sie die entsprechende SQL-Anweisung. Obwohl diese Methode umständlich erscheint, ist sie äußerst flexibel und ermöglicht es uns

    Vergleich und Differenzanalyse zwischen SpringBoot und SpringMVC Vergleich und Differenzanalyse zwischen SpringBoot und SpringMVC Dec 29, 2023 am 11:02 AM

    SpringBoot und SpringMVC sind beide häufig verwendete Frameworks in der Java-Entwicklung, es gibt jedoch einige offensichtliche Unterschiede zwischen ihnen. In diesem Artikel werden die Funktionen und Verwendungsmöglichkeiten dieser beiden Frameworks untersucht und ihre Unterschiede verglichen. Lassen Sie uns zunächst etwas über SpringBoot lernen. SpringBoot wurde vom Pivotal-Team entwickelt, um die Erstellung und Bereitstellung von Anwendungen auf Basis des Spring-Frameworks zu vereinfachen. Es bietet eine schnelle und einfache Möglichkeit, eigenständige, ausführbare Dateien zu erstellen

    Wie SpringBoot Redis anpasst, um die Cache-Serialisierung zu implementieren Wie SpringBoot Redis anpasst, um die Cache-Serialisierung zu implementieren Jun 03, 2023 am 11:32 AM

    1. Passen Sie den RedisTemplate1.1-Standard-Serialisierungsmechanismus an. Die API-basierte Redis-Cache-Implementierung verwendet die RedisTemplate-Vorlage für Daten-Caching-Vorgänge. Öffnen Sie hier die RedisTemplate-Klasse und zeigen Sie die Quellcodeinformationen der Klasse publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations an. Schlüssel deklarieren, verschiedene Serialisierungsmethoden des Werts, der Anfangswert ist leer @NullableprivateRedisSe

    So erhalten Sie den Wert in application.yml in Springboot So erhalten Sie den Wert in application.yml in Springboot Jun 03, 2023 pm 06:43 PM

    In Projekten werden häufig einige Konfigurationsinformationen benötigt. Diese Informationen können in der Testumgebung und in der Produktionsumgebung unterschiedliche Konfigurationen haben und müssen möglicherweise später basierend auf den tatsächlichen Geschäftsbedingungen geändert werden. Wir können diese Konfigurationen nicht fest im Code codieren. Am besten schreiben Sie sie in die Konfigurationsdatei. Sie können diese Informationen beispielsweise in die Datei application.yml schreiben. Wie erhält oder verwendet man diese Adresse im Code? Es gibt 2 Methoden. Methode 1: Wir können den Wert, der dem Schlüssel in der Konfigurationsdatei (application.yml) entspricht, über den mit @Value versehenen Wert erhalten. Diese Methode eignet sich für Situationen, in denen es relativ wenige Mikrodienste gibt: Tatsächlich Projekte, wenn das Geschäft kompliziert ist, Logik

    See all articles