什么叫aop
aop是面向切面编程,它是面向对象编程oop的一种补充,它可以在不修改源代码的情况下,对程序添加统一的状态
为什么要用aop
AOP 又称面向方面编程,采取横向抽取机制(动态代理的方式),取代了传统纵向继承机制的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。
主要作用是分离功能性需求和非功能性需求,使开发人员可以集中处理某一个关注点或者横切逻辑,减少对业务代码的侵入,增强代码的可读性和可维护性。
简单的说,AOP 的作用就是保证开发者在不修改源代码的前提下,为系统中的业务组件添加某种通用功能。
aop要用在哪里
aop最常用的地方就是日志记录、事务管理、权限分配、性能检测
其中所用到的最主要的术语有以下几种:
Joinpoint 连接点:指那些被拦截到的点,在String中,指可以被动态代理拦截的目标类的方法
Poincut 切入点:对那些joinpoint进行拦截,切入就是从哪里开始不让运行的意思
Advice通知:指拦截到之后需要做的事情
Target目标:被拦截的目标
Weaving植入:指把增强代码应用到目标上,生成代理对象的过程
Proxy代理:指生成的代理对象
Aspect切面:切点和通知的结合
其中Advice通知又可以分为
before前置通知:通知方法在目标调用之前执行
after后置通知:通知方法在目标方法返回或异常后调用
after-returning返回后通知:通知方法会在目标方法返回后调用
after-throwing抛出异常时通知:通知方法会在没慕白哦方法抛出异常后调用
around环绕通知:通知方法会将目标方法封装起来
第一先添加依赖
第二创建xml文件
第三创建接口,实现类,切面类,测试类
//接口
public interface AaaJie {
int add(int a,int b);
}
//实现接口类
@Service//使String容器可以扫描到这个实现类
public class AaaJieImpl implements AaaJie{
@Override
public int add(int a, int b) {
System.out.println("----------add方法运行了");
return a+b;
}
}
//测试类
public class text01 {
public static void main(String[] args) {
//加载spring配置文件
ApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
AaaJie aaaJieImpl = (AaaJie) app.getBean("aaaJieImpl");
int add = aaaJieImpl.add(10, 10);
System.out.println(add);
}
}
@Aspect //标记该类为切面类
@Component //相当于@Service 将类对象交由String创建
public class Login {
@Pointcut(value = "execution(* gy.text.aop01.*.*(..))")
public void maodian(){}//这个方法什么也不写,只是用来做锚点,切入项目内部
//当有自定义注解注释的执行方法执行时,不论是否报错,都会执行以下内容
@After(value = "maodian()")
public void add(){
System.out.println("方法已经执行了,给个提醒");
}
//前置通知
@Before(value = "maodian()")
public void adds(){
System.out.println("执行方法之前,先执行这个的代码");
}
//后置返回通知,遇到return时, 如果方法出现异常,这个通知不会执行
@AfterReturning(value = "maodian()",returning = "r")//他会把方法执行的结果付给该变量
public void after(Override r){
System.out.println("=========这是方法执行完,返回的通知");
}
//异常通知,当切入的方法发生异常时,才会执行
@AfterThrowing(value = "maodian()")
public void afterThrowing(){
System.out.println("==================异常处理一下=================");
}
测试结果
还有最后一个以上所有通知的组合体 环绕通知
//环绕通知
@Around(value = "maodian()")
public Object huanRao(ProceedingJoinPoint joinPoint){//joinPoint 为连接点,理解为被执行的方法对象
//前置通知
System.out.println("这是前置通知------------");
try {
Object res = joinPoint.proceed();
System.out.println("------------这是后置通知");
} catch (Throwable e) {
e.printStackTrace();
System.out.println("------这是异常处理通知------");
} finally {
System.out.println("------------这是无论如何-----------都有的通知------------");
}
return 0;
}
原理就是将这个插入点当成一个程序的一部分方法体,然后把这些个通知都插到这个方法体的执行前,执行后,以及执行错误