什么是AOP
OOP(面向?qū)ο缶幊?提供“從上到下”的關(guān)系厅贪,而AOP(面向方面編程)提供一種“橫切”的方式蠢护,也可以說(shuō)是“從左到右”。
簡(jiǎn)單來(lái)說(shuō)就是將那些與業(yè)務(wù)無(wú)關(guān)养涮,卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來(lái)葵硕,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度贯吓,并有利于未來(lái)的可操作性和可維護(hù)性懈凹。
實(shí)例
可能光是說(shuō)AOP的定義,大家都不太能理解悄谐。
舉個(gè)例子介评,比如日志功能,實(shí)現(xiàn)這個(gè)功能的代碼可能是很多類所需要的功能之一尊沸,但是如果我們?cè)诿恳粋€(gè)類里都重復(fù)添加實(shí)現(xiàn)日志功能的代碼威沫,將會(huì)有很多重復(fù)代碼。
上代碼(代碼參考https://blog.csdn.net/JinXYan/article/details/89302126
)
/**
* @description: 業(yè)務(wù)類
*/
public class Calculator {
public int add(int i, int j) {
System.out.println("加法");
return i + j;
}
public int sub(int i, int j) {
System.out.println("減法");
return i - j;
}
public int mul(int i, int j) {
System.out.println("乘法");
return i * j;
}
public int div(int i, int j) {
System.out.println("除法");
return i / j;
}
}
通過(guò)切入點(diǎn)洼专,把業(yè)務(wù)類Calculator
“橫向”切開(kāi)棒掠,這樣很好的把業(yè)務(wù)類和日志類解耦。
/**
* @description: 日志切面類屁商,
*/
@Aspect
public class LogAspects {
//切入點(diǎn)
@Pointcut("execution(public int Calculator.*(..))")
public void pointCut(){};
//代表在目標(biāo)方法執(zhí)行前切入, 并指定在哪個(gè)方法前切入
@Before("pointCut()")
public void logStart(){
System.out.println("@Before");
}
//代表在目標(biāo)方法運(yùn)行結(jié)束之后 ,不管有沒(méi)有異常
@After("pointCut()")
public void logEnd(){
System.out.println("@After");
}
//代表在目標(biāo)方法正常返回值后運(yùn)行
@AfterReturning("pointCut()")
public void logReturn(){
System.out.println("@AfterReturning");
}
//代表在目標(biāo)方法出現(xiàn)異常后運(yùn)行
@AfterThrowing("pointCut()")
public void logException(){
System.out.println("@AfterThrowing");
}
//動(dòng)態(tài)代理,手動(dòng)執(zhí)行joinPoint.procced方法(程序執(zhí)行過(guò)程中明確的點(diǎn)烟很,一般指方法的調(diào)用)
//簡(jiǎn)單的來(lái)說(shuō)就是,在目標(biāo)方法執(zhí)行之前是前置通知蜡镶,在目標(biāo)方法執(zhí)行之后是后置通知
@Around("pointCut()")
public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("@Around:執(zhí)行目標(biāo)方法之前...");
Object obj = proceedingJoinPoint.proceed();
System.out.println("@Around:執(zhí)行目標(biāo)方法之后...");
return obj;
}
}
/**
* @description: 配置類
*/
@Configuration
@EnableAspectJAutoProxy
public class Config {
@Bean
public Calculator calculator(){
return new Calculator();
}
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
測(cè)試一下
public class test {
public static void main(String[] args) {
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Config.class);
Calculator c = app.getBean(Calculator.class);
c.add(2, 3);
}
}
運(yùn)行結(jié)果