一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java開發AOP面向切面編程入門

java開發AOP面向切面編程入門

2022-02-17 14:44guoyp2126 Java教程

這篇文章主要介紹了java開發的AOP面向切面編程入門的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步學有所得

 

引言

在實際應用場景中,我們封裝一個學生的類,這個類用于封裝學生的日常行為,如:上學、吃飯、上課等。然而,在疫情期間,學生上學時入校、吃飯時進入餐廳,需要測溫查驗證件等行為,拿到這樣的需求我們怎么辦?

 

不好的解決方案

 

面向過程的解決方案

遇到問題解決問題,在上學、吃飯方法中加上測溫、查驗證件方法,或者在學生類中提煉一個測溫查驗證件私有的方法,在需要時調用。

代碼如下:

public class Student {
    public void toSchool(){
        check();
        System.out.println("高高興興去上學!");
    }
    public void toEat(){
        check();
        System.out.println("一號餐廳去吃飯!");
    }

    public void toClass(){
        System.out.println("排排坐,聽講座!");
    }

    public void getUp(){
        System.out.println("起床啦!");
    }
    
    private void check(){
        System.out.println("查驗證件、測體溫");
    }
}

這種方式存在問題只是頭痛醫頭、腳痛醫腳,代碼硬拷貝,現在教師進校門也要查驗證件測溫,如何辦?將check代碼復制到教師類中,再者,如果check()中業務規則發生變化,則需要到處改代碼,顯然是一種非常蹩腳的解決方案。

 

使用繼承解決方案

創建一個man的基類,將check()方法放到該類中,教師、學生均繼承此類,子類調用這個方法即可,

代碼如下:

public class Man {
    protected void check(){
        System.out.println("查驗證件、測體溫");
    }
}
public class Student extends Man {

    public void toSchool(){
        check();
        System.out.println("高高興興去上學!");
    }

    public void toEat(){
        check();
        System.out.println("一號餐廳去吃飯!");
    }
}

public class Teacher extends Man {
    public void toSchool(){
        check();
        System.out.println("高高興興去上班!");
    }

    public void toEat(){
        check();
        System.out.println("教工餐廳去吃飯!");
    }

    public void toClass(){
        System.out.println("排排坐,聽講座!");
    }
}

這種方式,雖然解決了代碼復制問題,但違背了面向對象程序設計的單一職責原則,因為查驗證件測溫等均不是學生或教師應該擁有的職責,類的劃分職責不清,增加了代碼擴展維護的難度。

 

使用聚合的解決方案

將查驗證件測溫等行為封裝一個獨立的類,學生和教師的依然只封裝他們固有的方法,

代碼如下:

public class Checktor {
    public void takeTemperature(){
        System.out.println("查驗證件、測體溫");
    }
}
public class Student {
    private Checktor checktor = new Checktor();

    public void toSchool(){
        checktor.takeTemperature();
        System.out.println("高高興興去上學!");
    }

    public void toEat(){
        checktor.takeTemperature();
        System.out.println("一號餐廳去吃飯!");
    }
}

這種方法很好的解決了面向對象程序設計單一職責原則,體現了類的封裝性,但是代碼侵入性很強,而且代碼僵化,維護性差。如疫情結束了,我們要求取消查驗證件和測溫,就需要改原有的代碼,破壞了開閉原則,增加了程序員的工作量。有些人寫配置開關變量,在調用時使用ifelse進行判斷是否調用也能遵循開關變量,但是代碼中包含了一些可能用不到代碼,不優雅,不是很好解決方案。

 

面向切面的編程基本概念

面向切面的編程是不破壞原有類封裝性的前提下,動態在其方法前面(before)、后邊(after)及周圍(Around)(前面和后邊)增強功能。

  • 連接點(Joinpoint):目標對象中每個方法前面、后面均為連接點。如學生類中toSchool、toEat、toClass、getUp方法前面后面均是切入點;
  • 切入點(Point):需要增強功能方法前面或后面,是切入點,如進學校前、吃飯前需要測體溫,則toSchool、toEat兩個方法前是切入點,其余的不是;

java開發AOP面向切面編程入門

  • 切面類(Aspect):也稱通知類,封裝了需要增強功能的類,如:Checktor;
  • 通知方法(advice):需要增強的功能,如:測溫方法;
  • 通知類型:前置通知(Before)、后置通知(After)、環繞通知(around)、異常通知(throwing)、最終通知(after (finally) advice);

java開發AOP面向切面編程入門

  • 代理(proxy):將通知應用到目標對象實現機制,是通過創建代理對象完成的
  • 織入(Weaving):將切面代碼插入到目標對象上,生成代理對象的過程

 

基于Spring面向切面程序實現

針對學生上學場景,Spring的使用XML和注解兩設計種方式完成面向切面的編程。
工程依賴項:在maven pom文件中,需要引入以下依賴項

     <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjtools</artifactId>
      <version>1.8.9</version>
    </dependency>

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.5.4</version>
    </dependency>

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.5</version>
      <scope>runtime</scope>
    </dependency>

XML方式:
學生類:

public class Student {

    public void toSchool(){
        System.out.println("高高興興去上學!");
    }

    public void toEat(){
        System.out.println("一號餐廳去吃飯!");
    }

    public void toClass(){
        System.out.println("排排坐,聽講座!");
    }

    public void getUp(){
        System.out.println("起床啦!");
    }
}

切面類:

public class Checktor {
    public void takeTemperature(){
        System.out.println("測體溫啦!");
    }

    public void washHand(){
        System.out.println("洗洗手更健康!");
    }
}

xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.bjwl.*"/>
    <!--目標(業務)對象-->
    <bean id="student" class="com.bjwl.xmltest.Student"/>
    <bean id="teacher" class="com.bjwl.xmltest.Teacher"/>
    <!--通知(切面)對象-->
    <bean id="checktor" class="com.bjwl.xmltest.Checktor"></bean>

    <aop:config>
        <!--定義(切面)對象-->
        <aop:aspect ref="checktor">
            <!--定義切點-->
            <aop:pointcut id="point_test_d" expression="execution(* com.bjwl.xmltest.Student.to*(..))"/>
            <!--定義通知-->
            <aop:before method="takeTemperature" pointcut-ref="point_test_d"></aop:before>
            <aop:after method="washHand" pointcut-ref="point_test_d"></aop:after>
        </aop:aspect>
    </aop:config>
</beans>

其中:目標對象是student對象,切點是student對象中方法名前兩個字母是to的所有方法,事前執行測溫(takeTemperature)、事后執行洗手(washHand)
測試代碼如下:

public class StudentTest {
    @Test
    public void toSchool() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "bean02.xml"
        );
        Student student = (Student)applicationContext.getBean("student");
        student.toSchool();
    }
 } 

運行結果如下:

java開發AOP面向切面編程入門

如果教師需也需要測溫,編寫教師類,代碼如下:

public class Teacher {
    public void toSchool(){
        System.out.println("高高興興去上班!");
    }

    public void toEat(){
        System.out.println("教工餐廳去吃飯!");
    }

    public void toClass(){
        System.out.println("排排坐,聽講座!");
    }
}

xml文件更改如下:

    <aop:config>
        <!--定義(切面)對象-->
        <aop:aspect ref="checktor">
            <!--定義切點-->
            <aop:pointcut id="point_test_d" expression="execution(* com.bjwl.xmltest.*.to*(..))"/>
            <!--定義通知-->
            <aop:before method="takeTemperature" pointcut-ref="point_test_d"></aop:before>
            <aop:after method="washHand" pointcut-ref="point_test_d"></aop:after>
        </aop:aspect>
    </aop:config>

則表示com.bjwl.xmltest中的所有類的對象均為目標對象,前兩個字母帶to的方法前后均為切點。

注解方式:
學生類代碼:

java開發AOP面向切面編程入門

切面類的代碼

java開發AOP面向切面編程入門

xml文件:

java開發AOP面向切面編程入門

運行結果等同,XML文件。

這樣做的好處,學生類、教師類、切面類具有職責單一性,提現業務邏輯封裝性,動態增強符合開閉原則。

 

小結

以上簡單的介紹了面向切面編程的基本概念和基本用法。用好面向切面的編程技術很不易,因為切點只能設置到需要增強功能前面或后面,對程序設計人員要求很高,要求能夠根據編程經驗和技巧設計出合理的切點,需要提現類的層次性。如:執行SQL語句前,在控制臺輸出完整的SQL語句的切點,切點就不能設置到你自己定義的Dao中,而是設置在PrepareStatement的exectuce的方法前。不過也不用擔心,使用各種框架時,常用的日志等,已經給我們設置了開關變量,我們直接使用即可,非常簡單。

以上就是java開發AOP面向切面編程入門的詳細內容,更多關于java面向切面編程的資料請關注服務器之家其它相關文章!

原文鏈接:https://blog.csdn.net/guoyp2126/article/details/120247685

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 男人的天堂久久精品激情 | 亚洲精品色综合久久 | 日韩亚洲人成在线 | 国产青青草 | 四虎影院新地址 | 青青青久久久 | 久久精品国产视频澳门 | 教练你好大轻点漫 | 欧美日韩亚洲第一区在线 | 欧美丰满大乳大屁在线观看股 | 精品图区| 女性性色生活片免费观看 | 午夜福利试看120秒体验区 | 久久噜国产精品拍拍拍拍 | 亚洲乱码尤物193yw在线播放 | 精品久久久噜噜噜久久7 | 单亲乱l仑在线观看免费观看 | 欧美bbxx | 3x免费高清视频 | 亚洲图片综合网 | 国产东北3p真实在线456视频 | 免费看h片的网站 | 亚洲视频在线一区二区 | 99久久国产综合精品麻豆 | 麻豆自拍 | 亚洲激情 欧美 | xxxx意大利xxxxhd | 天堂久久久久va久久久久 | 青青草精品在线 | 黑人巨大videosjapan高清 黑人好大 | 99热r| 欧洲老太玩小伙 | 婷婷色综合网 | sxx免费看视频在线播放 | china国产bbw | 香蕉久久久| hd性欧美俱乐部中文 | 日日爱爱| 波多野结衣中文字幕在线 | 免费看男女污污完整版 | 国产日韩欧美在线一二三四 |