Spring框架AOP面向切面編程原理全面分析
1.什么是AOP
AOP:Aspect Oriented Programming ⾯向切⾯編程。
AOP面向切面的優(yōu)勢
- 降低模塊之間的耦合度。
- 使系統(tǒng)更容易擴展。 更好的代碼復(fù)⽤。
- ⾮業(yè)務(wù)代碼更加集中,不分散,便于統(tǒng)⼀管理。
- 業(yè)務(wù)代碼更加簡潔存粹,不參雜其他代碼的影響。
AOP 是對⾯向?qū)ο缶幊痰?#12032;個補充,在運⾏時,動態(tài)地將代碼切⼊到類的指定⽅法、指定位置上的編程 思想就是⾯向切⾯編程。將不同⽅法的同⼀個位置抽象成⼀個切⾯對象,對該切⾯對象進⾏編程就是 AOP。
AOP需要添加的依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.3.9</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.9</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.9</version> </dependency>
2.簡述AOP工作運行原理
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; public class MyInvocationHandler implements InvocationHandler { private Object object=null; public Object bind(Object object){ this.object=object; return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName()+"方法的參數(shù)"+ Arrays.toString(args)); Object result=method.invoke(this.object,args); System.out.println(method.getName()+"的結(jié)果是"+result); return result; } }
以上是動態(tài)創(chuàng)建AOP的方法,首先通過bind返回
Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass.getInterfaces(),this)返回代理對象
接著運用反射的invoke方法,實現(xiàn)面向切面編程
用method.getName()獲取方法名
用arg獲取屬性
動態(tài)創(chuàng)建的總結(jié):
以上是通過動態(tài)代理實現(xiàn) AOP 的過程,⽐較復(fù)雜,不好理解,Spring 框架對 AOP 進⾏了封裝,使⽤ Spring 框架可以⽤⾯向?qū)ο蟮乃枷雭韺崿F(xiàn) AOP
3.使用Spring創(chuàng)建AOP
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; import java.util.Arrays; @Aspect @Component public class LoggerAspect { //@before表適方法執(zhí)行的具體位置和時機 @Before("execution(public int Util.impl.Calimpl.*(..))") public void before(JoinPoint joinPoint){ //獲取方法名 String name=joinPoint.getSignature().getName(); //獲取參數(shù) String args= Arrays.toString(joinPoint.getArgs()); System.out.println(name+"方法的參數(shù)是"+args); } @After("execution(public int Util.impl.Calimpl.*(..))") public void after(JoinPoint joinPoint){ String name=joinPoint.getSignature().getName(); System.out.println(name+"執(zhí)行完畢"); } @AfterReturning(value = "execution(public int Util.impl.Calimpl.*(..))",returning = "result") public void returning(JoinPoint joinPoint,Object result){ System.out.println("結(jié)果是:"+result); } }
注解@Aspect指的是面向切面編程
@Component指的是交給Ioc容器管理
通過Joinpoint.getSignature().getname()獲取方法名
然后實現(xiàn)在調(diào)用這個方法前,進行運行所需要的日志信息
測試類
import Util.Cal; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test2 { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-aop.xml"); Cal proxy = (Cal) applicationContext.getBean("calimpl"); proxy.add(1,1); } }
還是通過Application 讀取Spring.xml 再將getBean 默認小寫名字,再調(diào)用方法即可
Spring.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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd "> <!-- ⾃動掃描 --> <context:component-scan base-package="Util"> </context:component-scan> <!-- 是Aspect注解⽣效,為⽬標類⾃動⽣成代理對象 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
以上就是Spring框架AOP面向切面編程全面分析的詳細內(nèi)容,更多關(guān)于Spring框架AOP面向切面的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
區(qū)分Java中的ArrayList和LinkedList
這篇文章主要介紹了如何區(qū)分Java中ArrayList和LinkedList,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-06-06springboot集成開發(fā)實現(xiàn)商場秒殺功能
這篇文章主要介紹了springboot集成實現(xiàn)商品秒殺功能,秒殺系統(tǒng)業(yè)務(wù)流程,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12spring boot項目沒有mainClass如何實現(xiàn)打包運行
這篇文章主要介紹了spring boot項目沒有mainClass如何實現(xiàn)打包運行,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01