Aop和SpringAop

58 阅读3分钟

Aop是什么

AOP是一种思想(面向切面编程),是一种编程规范,用于划分方法中的核心业务和非核心业务,解方法的耦合,提高方法的复用性.AOP通过将切点把非核心业务从核心业务逻辑中分离出来,使得这些切点可以在整个项目中随意地复用。

切点是指在项目中存在的与业务逻辑无关的功能和服务,比如日志记录、安全性、事务管理、异常处理等。这些关注点通常跨越多个模块或类,散布在整个项目中,难以集中管理和修改。

AOP采用切面(aspect)的概念来解决这个问题。切面是与横切关注点相关的行为集合,它定义了在何时何地将特定的关注点应用到目标对象中。通过使用切面,开发人员可以将关注点从核心业务逻辑中分离出来,并将其集中定义和管理。

SpringAop是什么

SpringAop是Spring框架提供的一种AOP实现方式,它基于原生的Java动态代理或cglib字节码生成技术来实现切面编程。

Spring AOP允许开发人员在不修改原始代码的情况下,通过将切面逻辑写入到目标对象的方法中,达到在特定的切点处执行额外操作的目的.

Spring AOP可以通过XML配置或注解来定义切面和通知,开发人员可以根据需要选择使用哪种方式。Spring AOP提供了诸如前置通知、后置通知、环绕通知、异常通知和最终通知等不同类型的通知,以满足各种需求

总的来说,Spring AOP提供了一种简洁、灵活的方式来实现切面编程,使得开发人员可以通过配置来管理和应用切面,从而更好地实现关注点的分离和重用。

动态代理

  • 如果有接口,就采用jdk动态代理
  • 如果没接口,就采用cglib的方式
  • 在实现类被final修饰时不能使用动态代理

jdk动态代理

public class JDKProxyFactory {
    public static Object getProxy(Class clazz){
        Object proxy = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Logger logger = new Logger();
                Object obj = null;
                try {
                    // 前置增强
                    logger.m1();
                    // method.invoke:被代理的对象执行方法
                    obj = method.invoke(clazz.newInstance(), args);
                    // 后置增强
                    logger.m2();
                } catch (Exception e) {
                    logger.m3();
                }
                return obj;
            }
        });
        return proxy;
    }

cglib动态代理

public class CglibProxyFactory {

    public static Object getProxy(Class clazz){
        // 创建一个代理工具类
        Enhancer enhancer = new Enhancer();
        // 根据父类创建子类对象
        enhancer.setSuperclass(clazz);
        // 调用代理对象的方法(增强的代码写在这里)
        enhancer.setCallback(new InvocationHandler() {
            @Override
            // 参数一;代理对象本身(用不上)
            // 参数二:代理对象方法
            // 参数三:方法的参数
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                Logger logger = new Logger();
                Object invoke = null;
                try {
                    //前置增强
                    logger.m1();

                    // 执行被代理对象的方法
                    invoke = method.invoke(clazz.newInstance(), objects);
                    //后置置增强
                    logger.m2();
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.m3();
                }
                return invoke;
            }
        });

        Object proxy = enhancer.create();
        return proxy;
    }
}