Spring框架AOP面向切面編程原理全面分析
1.什么是AOP
AOP:Aspect Oriented Programming ⾯向切⾯編程。
AOP面向切面的優(yōu)勢
- 降低模塊之間的耦合度。
- 使系統(tǒng)更容易擴(kuò)展。 更好的代碼復(fù)⽤。
- ⾮業(yè)務(wù)代碼更加集中,不分散,便于統(tǒng)⼀管理。
- 業(yè)務(wù)代碼更加簡潔存粹,不參雜其他代碼的影響。
AOP 是對⾯向?qū)ο缶幊痰?#12032;個補(bǔ)充,在運⾏時,動態(tài)地將代碼切⼊到類的指定⽅法、指定位置上的編程 思想就是⾯向切⾯編程。將不同⽅法的同⼀個位置抽象成⼀個切⾯對象,對該切⾯對象進(jìn)⾏編程就是 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 進(jìn)⾏了封裝,使⽤ 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í)行的具體位置和時機(jī)
@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)用這個方法前,進(jìn)行運行所需要的日志信息
測試類
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 默認(rèn)小寫名字,再調(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注解⽣效,為⽬標(biāo)類⾃動⽣成代理對象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
以上就是Spring框架AOP面向切面編程全面分析的詳細(xì)內(nèi)容,更多關(guān)于Spring框架AOP面向切面的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring mvc整合tiles框架的簡單入門教程(maven)
這篇文章主要給大家介紹了關(guān)于Spring mvc整合tiles框架的簡單入門教程(maven),文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考借鑒,下面來一起看看詳細(xì)的介紹吧。2017-12-12
Java 數(shù)據(jù)結(jié)構(gòu)鏈表操作實現(xiàn)代碼
這篇文章主要介紹了Java 數(shù)據(jù)結(jié)構(gòu)鏈表操作的相關(guān)資料,并附實例代碼,需要的朋友可以參考下2016-10-10
java讀取文件內(nèi)容的三種方法代碼片斷分享(java文件操作)
本文介紹java讀取文件內(nèi)容的三種方法,代碼可以直接放到程序中使用,大家參考使用吧2014-01-01
Jpa?Specification如何實現(xiàn)and和or同時使用查詢
這篇文章主要介紹了Jpa?Specification如何實現(xiàn)and和or同時使用查詢,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11
解析Oracle數(shù)據(jù)庫中的對象集合schema
這篇文章主要介紹了Oracle數(shù)據(jù)庫中的對象集合schema,是Oracle數(shù)據(jù)庫入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-11-11
詳解Spring Cloud Eureka多網(wǎng)卡配置總結(jié)
本篇文章主要介紹了詳解Spring Cloud Eureka多網(wǎng)卡配置總結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04

