Spring_202311_21_2 2. AOP面向切面编程

发布时间 2023-11-21 12:31:24作者: Kbaor

Spring_202311_21_2 2. AOP面向切面编程

AOP:全称是 Aspect Oriented Programming 即:面向切面编程。
简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。
即当需要扩展功能时,传统方式采用纵向继承方式实现。但这种方式有很多缺点。 比如:父类方法名称改变时,子类也要修改。给多个方法扩展功能时,子类也需要修改。 因此,spring的AOP,实际上是采用横向抽取机制,取代传统的纵向继承体系。

  1. AOP术语
    a) 通知、连接点、切入点、切面、引入、目标 等
  2. AOP =>JDK动态代理的方式
    a) 需求:在每个方法执行前输出“此方法开始运行”,在每个方法之后输出“此方法运行结束”
    b) 具体操作步骤:
    image
  • 创建目标类:UserService/UserServiceImpl
package com.bboy.service.impl;

import com.bboy.service.UserService;

/**
 * @类描述:
 * @作者:秦帅
 * @时间:2023/11/21 0021 11:31:52
 */
public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("===========>addUser");
    }

    @Override
    public void updateUser() {
        System.out.println("===========>updateUser");
    }

    @Override
    public void deleteUser() {
        System.out.println("===========>deleteUser");
    }
}

  • 创建切面类:MyLogAspect
package com.bboy.aspect;

/**
 * @类描述:
 * @作者:秦帅
 * @时间:2023/11/21 0021 11:39:45
 */
public class MyLogAspect {
    public void methodsBefore(){
        System.out.println("===========>此方法开始执行");
    }
    public void methodsAfter(){
        System.out.println("===========>此方法执行结束");
    }
}

  • 创建代理类:(目标类与切面类进行结合)
package com.bboy.factory;
//-将目标类与切面类结合

import com.bboy.aspect.MyLogAspect;
import com.bboy.service.UserService;
import com.bboy.service.impl.UserServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @类描述:
 * @作者:秦帅
 * @时间:2023/11/21 0021 11:45:12
 */
public class MyAspectFactory {
    //-: 获取结合之后的目标类
    public static UserService createService() {
        // -1. 目标类
        final UserService userService = new UserServiceImpl();
        // -2. 切面类
        MyLogAspect myLogAspect = new MyLogAspect();
        // -3. jdk动态代理的形式,将目标类与切面类进行结合
        return (UserService) Proxy.newProxyInstance(
                MyLogAspect.class.getClassLoader(),  //-当前类
                userService.getClass().getInterfaces(),//-目标类
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        //-: 前执行(调用切面类的方法)
                        myLogAspect.methodsBefore();
                        //-: 执行目标类的方法
                        Object obj = method.invoke(userService, args);
                        //-: 后执行(调用切面类的方法)
                        myLogAspect.methodsAfter();
                        return obj;
                    }
                }
        );


    }

}

  • 创建测试类
package com.bboy.demo;

import com.bboy.factory.MyAspectFactory;
import com.bboy.service.UserService;

/**
 * @类描述:
 * @作者:秦帅
 * @时间:2023/11/21 0021 12:05:30
 */
public class Demo {
    public static void main(String[] args) {
        UserService userService = MyAspectFactory.createService();
        userService.addUser();
        userService.deleteUser();
        userService.updateUser();
    }
}

  • 运行结果
    image