亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于AspectJ注解方式實(shí)現(xiàn)AOP

 更新時(shí)間:2023年09月08日 10:56:41   作者:96歲對(duì)抗java  
這篇文章主要介紹了基于AspectJ注解方式實(shí)現(xiàn)AOP,使用AspectJ的注解可以更方便地編寫(xiě)和管理切面邏輯,而Spring AOP也是使用了AspectJ提供的注解來(lái)實(shí)現(xiàn)切面編程,需要的朋友可以參考下

基于AspectJ實(shí)現(xiàn)AOP(注解方式)

這里我們采用的是非完全注解方式

1. 創(chuàng)建類(lèi), 在類(lèi)里面定義方法(連接點(diǎn))

package com.ffyc.spring.aop;
//被增強(qiáng)的類(lèi)(也就是被代理的類(lèi))
public class User {
    //被增強(qiáng)的方法(也就是被代理的方法)
    public void add(){
        System.out.println("add...");
    }
}

2. 創(chuàng)建增強(qiáng)類(lèi), 編寫(xiě)增強(qiáng)邏輯

  • 注意: 此時(shí)我們并沒(méi)有給增強(qiáng)類(lèi)添加注解來(lái)生成代理對(duì)象, 也沒(méi)有配置通知(增強(qiáng)的邏輯)
package com.ffyc.spring.aop;
//增強(qiáng)類(lèi)
public class UserProxy {
    //前置通知
    public void before(){
        System.out.println("before");
    }
    //這里還有后置通知, 異常通知, 環(huán)繞通知, 最終通知等, 現(xiàn)在邏輯先省略
}

3. 進(jìn)行通知的配置

①: 在spring配置文件中, 開(kāi)啟注解掃描與開(kāi)啟注解自動(dòng)生成代理對(duì)象

  • 注解掃描大家都知道: 就是componentScan
  • 注解自動(dòng)生成代理對(duì)象是什么?
    • 就是開(kāi)啟了注解自動(dòng)生成代理對(duì)象之后當(dāng)SpringIOC容器掃描basePackages的時(shí)候如果掃描到某個(gè)類(lèi)上面有@Aspect注解, 則會(huì)生成該類(lèi)的代理對(duì)象放到SpringIOC容器中由SpringIOC容器管理
      • 所以@Aspect注解就是在增強(qiáng)(通知)類(lèi)上添加的
<!--    開(kāi)啟組件掃描, 開(kāi)啟了組件掃描之后我們的spring容器就會(huì)在對(duì)應(yīng)的base-package位置進(jìn)行一個(gè)掃描-->
    <!--    注意: 其實(shí)我們的組件掃描也是可以通過(guò)使用注解的方式進(jìn)行配置-->
        <context:component-scan base-package="com.ffyc.spring"></context:component-scan>
<!--    開(kāi)啟Aspectj自動(dòng)生成代理對(duì)象-->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

②: 使用注解創(chuàng)建User和UserProxy類(lèi)的對(duì)象

  • 也就是讓SpringIOC容器幫我們創(chuàng)建
  • 在User類(lèi)和UserProxy類(lèi)上加上@Component注解即可
package com.ffyc.spring.aop;
import org.springframework.stereotype.Component;
//被增強(qiáng)的類(lèi)(也就是被代理的類(lèi))
@Component
public class User {
    //被增強(qiáng)的方法(也就是被代理的方法)
    public void add(){
        System.out.println("add...");
    }
}
package com.ffyc.spring.aop;
import org.springframework.stereotype.Component;
//增強(qiáng)類(lèi)
@Component
public class UserProxy {
    //前置通知
    public void before(){
        System.out.println("before");
    }
}

③: 在增強(qiáng)類(lèi)上面添加注解@Aspect

  • 這里注意: @Aspect注解要和@Component注解一起使用, 原因在最后
package com.ffyc.spring.aop;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
//增強(qiáng)類(lèi)
@Component
@Aspect
public class UserProxy {
    //前置通知
    public void before(){
        System.out.println("before");
    }
}

4. 配置不同類(lèi)型的通知

  • 在增強(qiáng)類(lèi)里面, 在作為通知的方法上面添加對(duì)應(yīng)的通知類(lèi)型的注解, 并使用切入點(diǎn)表達(dá)式將對(duì)應(yīng)的通知配置到某個(gè)切入點(diǎn)上
    • 這樣Spring底層就會(huì)幫我們根據(jù)我們添加的注解來(lái)創(chuàng)建代理對(duì)象
package com.ffyc.spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
//增強(qiáng)類(lèi)
@Component
@Aspect
public class UserProxy {
    @Pointcut(value = "execution(* com.ffyc.spring.aop.User.add(..))")
    private void method(){
    }
    //前置通知
    @Before(value = "execution (* com.ffyc.spring.aop.User.add(..))")
    public void before(){
        System.out.println("before...");
    }
    @AfterReturning(value = "method()")
    public void afterReturning(){
        System.out.println("afterReturning...");
    }
    @After(value = "execution(* com.ffyc.spring.aop.User.add(..))")
    public void after(){
        System.out.println("after...");
    }
    @AfterThrowing(value = "method()")
    public void afterThrowing(){
        System.out.println("afterThrowing...");
    }
    @Around(value = "method()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環(huán)繞前...");
        proceedingJoinPoint.proceed();
        System.out.println("環(huán)繞之后...");
    }
}
  • @PointCut注解用來(lái)創(chuàng)建一個(gè)切入點(diǎn), 該注解的value屬性(String類(lèi)型)為切入點(diǎn)表達(dá)式
  • @Around, @Before, @After, @AfterReturning, @AfterThrowing注解的value屬性(String類(lèi)型)都為切入點(diǎn)表達(dá)式
  • @AfterThrowing針對(duì)的是被代理方法拋出異常, 如果異常在內(nèi)部被解決, 那么并不會(huì)執(zhí)行@AfterThrowing通知
  • 我們通過(guò)JVM的學(xué)習(xí)可以知道, 如果方法是通過(guò)異常結(jié)束(指拋出異常), 那么肯定就不是正常退出(return), 那么也就意味著@AfterReturning(后置通知), 和@AfterThrowing(異常通知)只能同時(shí)觸發(fā)一個(gè)
  • @Around注解使用的時(shí)候要在參數(shù)位置預(yù)留一個(gè)ProceedingJoinPoint類(lèi)型的參數(shù), 最終會(huì)通過(guò)這個(gè)通知類(lèi)構(gòu)建一個(gè)被代理類(lèi)的代理對(duì)象, 這個(gè)代理對(duì)象是由Spring幫我們創(chuàng)建的, 所以這個(gè)通知類(lèi)也是Spring容器幫我們?nèi)呙璧? 對(duì)應(yīng)的@Around注解標(biāo)注的方法肯定也是由Spring幫我們調(diào)用的, 而Spring調(diào)用的方法我們可以在參數(shù)位置寫(xiě)一個(gè)形參, 這個(gè)時(shí)候Spring默認(rèn)會(huì)對(duì)該參數(shù)類(lèi)型進(jìn)行一個(gè)自動(dòng)裝配(基于類(lèi)型的自動(dòng)裝配), 這里就會(huì)由Spring幫我們裝配一個(gè)ProceedingJoinPoint對(duì)象, 我們可以調(diào)用其中的proceed()方法, 調(diào)用proceed()方法就會(huì)執(zhí)行切入點(diǎn)方法(被增強(qiáng)的方法)
    • ProceedingJoinPoint : 正在進(jìn)行的連接點(diǎn)

5. 測(cè)試:

package com.ffyc.spring.aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
    @Test
    public void testAop(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        User user = applicationContext.getBean("user", User.class);
        System.out.println(user);
        user.add();
    }
}
  • 當(dāng)我們調(diào)用user對(duì)象的add()方法的時(shí)候其實(shí)會(huì)執(zhí)行代理對(duì)象的add()方法

各個(gè)通知的執(zhí)行順序:

環(huán)繞前[@Around(前)] --> 前置通知[@Before] --> 被增強(qiáng)方法(切入點(diǎn)) --> 環(huán)繞后(@Around(后)) --> 最終通知(@After) --> 后置通知[@AfterReturning] (或者異常通知[@AfterThrowing])

補(bǔ)充:

@Aspect注解為什么要和@Component注解一起使用, 按理將使用一個(gè)@Aspect注解不是就已經(jīng)是由SpringIOC榮IQ創(chuàng)建代理對(duì)象并交由SpringIOC容器管理了?

**官方文檔解釋如下: **

You may register aspect classes as regular beans in your Spring XML configuration, or autodetect them through classpath scanning - just like any other Spring-managed bean. However, note that the @Aspect annotation is not sufficient for autodetection in the classpath: For that purpose, you need to add a separate @Component annotation (or alternatively a custom stereotype annotation that qualifies, as per the rules of Spring’s component scanner).

翻譯:

您可以在Spring XML配置中注冊(cè)aspect類(lèi),或者通過(guò)類(lèi)路徑掃描自動(dòng)檢測(cè)它們,就像任何其他Spring管理bean一樣。但是,請(qǐng)注意,@aspect注釋對(duì)于在類(lèi)路徑中自動(dòng)檢測(cè)是不夠的:為了達(dá)到這個(gè)目的,您需要添加一個(gè)單獨(dú)的@component注解(或者根據(jù)Spring的組件掃描器的規(guī)則來(lái)定義一個(gè)定制的原型注解)

到此這篇關(guān)于基于AspectJ注解方式實(shí)現(xiàn)AOP的文章就介紹到這了,更多相關(guān)AspectJ實(shí)現(xiàn)AOP內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論