什么是AOP
OOP(面向?qū)ο缶幊?提供“從上到下”的關(guān)系,而AOP(面向方面編程)提供一種“橫切”的方式,也可以說是“從左到右”。
簡單來說就是將那些與業(yè)務(wù)無關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來,便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來的可操作性和可維護(hù)性。
實(shí)例
可能光是說AOP的定義,大家都不太能理解。
舉個(gè)例子,比如日志功能,實(shí)現(xiàn)這個(gè)功能的代碼可能是很多類所需要的功能之一,但是如果我們在每一個(gè)類里都重復(fù)添加實(shí)現(xiàn)日志功能的代碼,將會有很多重復(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;
}
}
通過切入點(diǎn),把業(yè)務(wù)類Calculator“橫向”切開,這樣很好的把業(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é)束之后 ,不管有沒有異常
@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í)行過程中明確的點(diǎn),一般指方法的調(diào)用)
//簡單的來說就是,在目標(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();
}
}
測試一下
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é)果