日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

重新学习Spring2——IOC和AOP原理彻底搞懂

發(fā)布時(shí)間:2023/12/3 javascript 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 重新学习Spring2——IOC和AOP原理彻底搞懂 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、AOP


1 Spring AOP 的實(shí)現(xiàn)原理

  • 是對(duì)OOP編程方式的一種補(bǔ)充。翻譯過(guò)來(lái)為“面向切面編程”。

  • 1 AspectJ是靜態(tài)代理的增強(qiáng):所謂靜態(tài)代理就是AOP框架會(huì)在便一階段生成AOP代理類(lèi),也叫編譯器增強(qiáng)。

  • 2 使用Spring AOP

    • 與AspectJ 的靜態(tài)代理不同,Spring AOP使用的是動(dòng)態(tài)代理,動(dòng)態(tài)代理指AOP框架不會(huì)去修改字節(jié)碼,而是在內(nèi)存中臨時(shí)生成一個(gè)AOP對(duì)象,這個(gè)AOP對(duì)象包含了目標(biāo)對(duì)象的全部方法,并在特定的切點(diǎn)做了增強(qiáng)處理,并回調(diào)原對(duì)象的方法。
    • Spring AOP中的動(dòng)態(tài)代理有兩種:JDK動(dòng)態(tài)代理(代理必須實(shí)現(xiàn)一個(gè)接口)、CGLIB動(dòng)態(tài)代理(代理可以不實(shí)現(xiàn)接口)
    • 幾個(gè)概念:
      • 切面(Advisor):是AOP中的一個(gè)術(shù)語(yǔ),表示從業(yè)務(wù)邏輯中分離出來(lái)的橫切邏輯比如性能監(jiān)控、日志處理、權(quán)限控制等
        這些功能都可以從核心的業(yè)務(wù)邏輯中抽離出去。可以解決代碼耦合的問(wèn)題,職責(zé)更加單一。封裝了增強(qiáng)和切點(diǎn)。
      • 增強(qiáng)(Advice):增強(qiáng)代碼的功能的類(lèi),橫切到代碼中。
      • 目標(biāo):目標(biāo)方法(JDK代理)或目標(biāo)類(lèi)(CGLIB代理)。
      • 代理:通過(guò)ProxyFactory類(lèi)生成,分為JDK代理、CGLIB代理。
      • 切點(diǎn):通過(guò)一個(gè)條件來(lái)匹配攔截的類(lèi),這個(gè)條件成為切點(diǎn)。
      • 連接點(diǎn):作為增強(qiáng)方法的入?yún)?#xff0c;可以獲取目標(biāo)方法的信息。
    • 增強(qiáng)
      • 織入(Weaving):將切面應(yīng)用到目標(biāo)對(duì)象并導(dǎo)致代理對(duì)象創(chuàng)建的過(guò)程。
        • 1 前置增強(qiáng)(Before):在目標(biāo)方法前調(diào)用。
        • 2 后置增強(qiáng)(AfterAdvice):在目標(biāo)方法后調(diào)用。
        • 3 環(huán)繞增強(qiáng)(AroundAdvice):將Before和After,甚至拋出增強(qiáng)和返回增強(qiáng)合到一起。
        • 4 返回增強(qiáng)(AfterReturningAdvice):在方法返回結(jié)果后執(zhí)行,該增強(qiáng)可以接收到目標(biāo)方法返回的結(jié)果。
        • 5 拋出增強(qiáng)(AfterThrowingAdvice):在目標(biāo)方法拋出對(duì)應(yīng)的類(lèi)型后執(zhí)行,可以接收到對(duì)應(yīng)的異常信息。
      • 引入增強(qiáng)(DeclareParentsAdvice):想讓程序在運(yùn)行的時(shí)候動(dòng)態(tài)實(shí)現(xiàn)某個(gè)接口,需要引入增強(qiáng)。
  • 3 注解:Spring + AspectJ

    • 1 對(duì)切面類(lèi)添加 @Aspect 注解將切面類(lèi)和目標(biāo)類(lèi)放入到IOC容器中,可以通過(guò)<context:component-scan base-package=""/>進(jìn)行掃描。
    • 2 添加增強(qiáng)方法(包括增強(qiáng)類(lèi)型和切點(diǎn)表達(dá)式,以及連接點(diǎn))。
    • 3 在Spring 配置文件中添加<aop:aspectj-autoproxy proxy-target-class="true"/> ,false表示只能代理接口(JDK動(dòng)態(tài)代理),true表示代理類(lèi)(CGLIB代理)。
    • 3.1 通過(guò)切點(diǎn)表達(dá)式(AspectJ execution)進(jìn)行攔截

      • 步驟一:配置pox.xml:
<!--Spring AOP依賴(lài)--> <dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version> </dependency>
  • 步驟二:spring-config.xml
<!-- 注解掃描--> <context:component-scan base-package="com.sean.aoptest"></context:component-scan> <!-- 設(shè)置aop動(dòng)態(tài)代理類(lèi)型:true為代理類(lèi),false為代理接口 --> <aop:aspectj-autoproxy proxy-target-class="true"/>
  • 步驟三:編寫(xiě)代碼,在這里我上傳一段測(cè)試代碼
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:spring-config-test.xml"}) public class SpringTest{@Autowiredprivate Student student;@Testpublic void test01(){System.out.println(student.say("zengxing"));} }@Component class Student implements Person{@Overridepublic String say(String name) {// TODO Auto-generated method stub // if (name.equals("zengxing")) { // throw new RuntimeException("名字不能是" + name); //要拋出運(yùn)行時(shí)異常 // }return "Hello, " + name;}}///* around before... before around after... after str:Hello, zengxing afterReturningAdvice Hello, zengxing *///@Aspect @Component class LoggingAspect{//前置@Before("execution(String say(String))")public void before(JoinPoint point){System.out.println("before");}//后置@After("execution(String say(String))")public void after(JoinPoint point){System.out.println("after");}//環(huán)繞@Around("execution(String say(String))")public Object around(ProceedingJoinPoint point) throws Throwable{System.out.println("around before...");Object result = point.proceed();System.out.println("around after...");return result;}//返回@AfterReturning(value="execution(String say(String))", returning="str")public void afterReturningAdvice(JoinPoint point, String str){System.out.println("str:" + str);System.out.println("afterReturningAdvice");}//拋出@AfterThrowing(value = "execution(String say(String))", throwing = "e")public void afterThrowingAdvice(JoinPoint point, Exception e){String message = e.getMessage();System.out.println(message);System.out.println("AfterThrowingAdvice...");} }
  • 3.2 通過(guò)切點(diǎn)注解表達(dá)式(AspectJ @annotation)進(jìn)行攔截

    • 開(kāi)發(fā)步驟:
      • 1 定義注解類(lèi)
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface AuthorityTag { }
  • 2 為切面類(lèi)中增強(qiáng)指定注解表達(dá)式
@Aspect @Component class AuthorityAspect{@Before("@annotation(com.sean.aoptest.AuthorityTag)")public void before(JoinPoint point){System.out.println("authority before");} }
  • 3 在目標(biāo)類(lèi)目標(biāo)方法上標(biāo)注注解
@Component //將對(duì)象放入到IOC容器中 class Car1 implements Wheel{@AuthorityTag //標(biāo)注切入的的增強(qiáng)@Overridepublic void run(){System.out.println("I am a car, i can run");} }
  • 4 小的知識(shí)點(diǎn)

    • 利用方法簽名編寫(xiě) AspectJ 切點(diǎn)表達(dá)式
      • execution * com.sean.Calculator.* (…):匹配Calculator中聲明的所有方法,
        第一個(gè) * 代表任意修飾符及任意返回值。第二個(gè) * 代表任意方法。…匹配任意數(shù)量的參數(shù)。若目標(biāo)類(lèi)與接口與該切面在同一個(gè)包中,可以省略包名。
      • execution public * Calculator.*(…):匹配ArithmeticCalculator 接口的所有公有方法。
      • execution public double Calculator.*(…):匹配Calculator中返回double類(lèi)型數(shù)值的方法。
      • execution public double Calculator.*(double, …):匹配第一個(gè)參數(shù)為double類(lèi)型的方法,…匹配任意數(shù)量任意類(lèi)型的參數(shù)。
      • execution public double Calculator.*(double, double):匹配參數(shù)類(lèi)型為double,double類(lèi)型的方法。
    • 可以結(jié)合切點(diǎn)表達(dá)式使用 &&, ||, ! 來(lái)合并。如:
      • execution(void run()) || execution(void say())
    • 切面優(yōu)先級(jí):
      • 可以通過(guò)實(shí)現(xiàn)Ordered接口或利用@Order注解指定。
      • 1 實(shí)現(xiàn)Ordered接口,getOrder()方法返回的值越小,優(yōu)先級(jí)越高。
      • 2 使用@Order注解,需要出現(xiàn)在注解中,同樣是值越小優(yōu)先級(jí)越高。

參考博客:https://blog.csdn.net/qq_16605855/article/details/73465865

總結(jié)

以上是生活随笔為你收集整理的重新学习Spring2——IOC和AOP原理彻底搞懂的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。