你們好,我是IT修真院深圳分院第12期的JAVA學員,一枚正直純潔善良的java程序員。html
今天給你們分享一下,修真院官網Java任務3,深度思考中的知識點—Spring Aop?java
1.背景介紹
一、什麼是AOP程序員
1)在OOP(面向對象編程)中,正是這種分散在各處且與對象核心功能無關的代碼(橫切代碼)的存在,使得模塊複用難度增長。
2)AOP則將封裝好的對象剖開,找出其中對多個對象產生影響的公共行爲,並將其封裝爲一個可重用的模塊,這個模塊被命名爲「切面」(Aspect)
3)切面將那些與業務無關,卻被業務模塊共同調用的邏輯提取並封裝起來,減小了系統中的重複代碼,下降了模塊間的耦合度,同時提升了系統的可維護性、提升了開發的效率和程序的可複用性。spring
二、AOP與OOP的區別編程
1)AOP能夠說是OOP(面向對象編程)的補充和完善。OOP引入封裝、繼承、多態等概念來創建一種對象層次結構,用於模擬公共行爲的一個集合。
2)不過OOP容許開發者定義縱向的關係,但並不適合定義橫向的關係
3)例如日誌功能。日誌代碼每每橫向地散佈在全部對象層次中,而與它對應的對象的核心功能毫無關係。對於其餘類型的代碼,如安全性、異常處理和透明的持續性也都是如此,這種散佈在各處的無關的代碼被稱爲橫切(cross cutting)。
4)在OOP設計中,它致使了大量代碼的重複,而不利於各個模塊的重用。 安全
三、AOP的思想app
1) AOP的核心思想是幫助咱們在擴展功能(方法)時能夠不依靠修改源代碼來實現。
2)其採起橫向抽取機制,規避了傳統面向對象中縱向繼承體系的重複性高耦合代碼。框架
2.知識剖析編碼
一、爲何要使用aopspa
1)爲了方便,用了aop能讓你少寫不少代碼 2)爲了更清晰的邏輯,可讓你的業務邏輯去關注本身自己的業務,而不去想一些其餘的事情,這些其餘的事情包括:安全,事物,日誌等。 3)爲了下降以前傳統面向對象中採用縱向繼承體系加強方法致使的耦合度太高的問題: 4)提升了代碼的複用性
二、淺析AOP思想的發展及原理
發展:修改源代碼————採用OOP縱向繼承體系————採用AOP橫向織入
實現原理:經過動態代理建立代理對象來實現,默認使用Java動態代理來建立AOP代理,當須要代理的類不是代理接口的時候,Spring會切換爲使用CGLIB代理
三、aop專業術語
1.通知(Advice):通知定義了切面是什麼以及什麼時候使用;裏面就是加強方法的邏輯,分爲前置加強,後置加強,環繞加強,最終加強,異常加強。
2.鏈接點(JoinPoint):鏈接點是在應用執行過程當中可以插入切面的一個點。這個點能夠是調用方法時,拋出異常時,甚至修改一個字段時。切面代碼能夠利用這些點插入到應用的正常流程中,並添加新的行爲。
3.切入點(Pointcut)*:切點有助於縮小切面所通知的鏈接點的範圍。(何處)
4.切面(Aspect)*:切面是通知和切點的結合。通知和切點定義了切面的所有內容——它是什麼,在什麼時候何處完成其功能。
5.目標(target):被加強的方法所在的那個類,也就是真正的業務邏輯,他能夠在絕不知情的狀況下,被織入切面。而本身專一於業務自己的邏輯。
6.代理(proxy):目標類被加強後產生的代理類
7.織入(weaving):把加強應用到目標類的過程
8:引入(Introduction) 引入容許咱們向現有的類添加新方法或屬性,從而無需修改這些現有類的狀況下,讓他們具備新的行爲和狀態
四、通知類型介紹
(1)Before:在目標方法被調用以前作加強處理,@Before只須要指定切入點表達式便可
(2)AfterReturning:在目標方法正常完成後作加強,@AfterReturning除了指定切入點表達式後,還能夠指定一個返回值形參名returning,表明目標方法的返回值
(3)AfterThrowing:主要用來處理程序中未處理的異常,@AfterThrowing除了指定切入點表達式後,還能夠指定一個throwing的返回值形參名,能夠經過該形參名 來訪問目標方法中所拋出的異常對象
(4)After:在目標方法完成以後作加強,不管目標方法時候成功完成。@After能夠指定一個切入點表達式
(5)Around:環繞通知,在目標方法完成先後作加強處理,環繞通知是最重要的通知類型,像事務,日誌等都是環繞通知,注意編程中核心是一個ProceedingJoinPoint
三、常見問題
一、實現AOP的方式有哪些?
二、實現加強的方法有那些?
三、在肯定好須要加強的方法以後,切入點的定位是如何完成的
四、使用@Aspect對SSM進行切入,統計運行時間。
4.解決方案
1):實現AOP的方式有哪些? 在sring裏面進行aop操做,使用aspectJ(AspectJ是一種擴展Java)來實現。aspectJ自己是一個單獨的面向切面的框架,裏面定義了AOP語法,不是spring的一部分,和spring協同完成springAOP的操做,使用aspectJ來實現springAOP的操做有兩種方式 1:繼承的類的方式(不推薦) 2:基於aspectJ的xml文件 3.基於aspectJ註解
2):實現加強的方法有那些?
織入 引入 3):在肯定好須要加強的方法以後,切入點的定位是如何完成的 能夠用execution表達式來解決(經常使用) 也能夠用xml配置,使用RegexpMethodPointcutAdvisor,來定義切點。 1.execution(* com.aop.add(..)) 2.匹配全部save開頭的方法:execution(* save*(..)) 4):使用@Aspect對SSM進行切入,統計運行時間。 在編碼實戰的時候講講。
5.編碼實戰
基於xml配置文件配置
須要建立aop對象,設置切入點、加強類、方法等。
基於註解方式配置文件
<context:component-scan base-package="anno"/> <aop:aspectj-autoproxy />
注意這裏儘量使用閉合標籤,不要使用,不然沒法正常切入<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
這裏上傳一個簡單的基於註解方式的aop demo
applicationContext.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="anno"/> <aop:aspectj-autoproxy /> </beans> UserService.java package anno; import org.springframework.stereotype.Service; @Service public class UserService { public void add(){ System.out.println("UserService add()"); } public boolean delete(){ System.out.println("UserService delete()"); return true; } public void edit(){ System.out.println("UserService edit()"); int i = 5/0; } } Operator.java package anno; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class Operator { @Pointcut("execution(* anno..*.*(..))") public void pointCut(){} @Before("pointCut()") public void doBefore(JoinPoint joinPoint){ System.out.println("AOP Before Advice..."); } @After("pointCut()") public void doAfter(JoinPoint joinPoint){ System.out.println("AOP After Advice..."); } @AfterReturning(pointcut="pointCut()",returning="returnVal") public void afterReturn(JoinPoint joinPoint,Object returnVal){ System.out.println("AOP AfterReturning Advice:" + returnVal); } @AfterThrowing(pointcut="pointCut()",throwing="error") public void afterThrowing(JoinPoint joinPoint,Throwable error){ System.out.println("AOP AfterThrowing Advice..." + error); System.out.println("AfterThrowing..."); } @Around("pointCut()") public void around(ProceedingJoinPoint pjp){ System.out.println("AOP Aronud before..."); try { pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("AOP Aronud after..."); } } Test.java package anno; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); UserService userService = (UserService) ctx.getBean("userService"); userService.add(); } }
運行結果
擴展思考
一、 基於註解與基於配置文件的優缺點.
優勢: 註解能減小配置的工做,並且配置信息和JAVA代碼放在一塊兒,有助於加強程序的內聚性。相對於XML配置文件進行配置文件和程序文件的切換,用註解方式,能提升開發的連貫性,和提成開發效率。 缺點: 程序複雜的話,仍是使用xml配置文件的方式,這樣可讀性和可維護性比較強。
https://www.cnblogs.com/liuru...
https://www.cnblogs.com/hongw...
https://blog.csdn.net/zghwaic...
更多討論
一、 基於註解與基於配置文件的優缺點有哪些?
優勢: 註解能減小配置的工做,並且配置信息和JAVA代碼放在一塊兒,有助於加強程序的內聚性。相對於XML配置文件進行配置文件和程序文件的切換,用註解方式,能提升開發的連貫性,和提成開發效率。 缺點: 程序複雜的話,仍是使用xml配置文件的方式,這樣可讀性和可維護性比較強。
二、實現AOP的方式有哪些?
在sring裏面進行aop操做,使用aspectJ(AspectJ是一種擴展Java)來實現。aspectJ自己是一個單獨的面向切面的框架,裏面定義了AOP語法,不是spring的一部分,和spring協同完成springAOP的操做,使用aspectJ來實現springAOP的操做有兩種方式 1:繼承的類的方式(不推薦) 2:基於aspectJ的xml文件 3.基於aspectJ註解
三、實現加強的方法有那些?
織入 引入
兩種方式
今天的分享就到這裏啦,歡迎你們點贊、轉發、留言、拍磚~