首页 > 技术文章 > spring AOP

jingpeng77 2020-06-02 18:26 原文

一、定义

面向切面编程(AOP)是对面向对象编程(OOP)的补充,面向对象编程擅长处理纵向问题,对横向问题无能为力,而面向切面编程主要解决的就是 横向问题。

AOP(Aspect-Oriented Programming)作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理等。

二、aop的应用场景有哪些:

场景一: 记录日志
场景二: 监控方法运行时间 (监控性能)
场景三: 权限控制
场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五: 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )

三、springAop的底层是怎样实现的?是编译时期进行织入,还是运行期进行织入?

1、JDK动态代理

2、CGLIB代理

运行期,生成字节码,再加载到虚拟机中,JDK是利用反射原理,CGLIB使用了ASM原理。

四、spring AOP 默认使用jdk动态代理还是cglib?

要看条件,如果实现了接口的类,是使用jdk。如果没实现接口,就使用cglib。

https://blog.csdn.net/u010452388/article/details/80868392

五 AOP的作用

作用:在不修改源代码的情况下,可以实现功能的增强。

 传统的纵向体系代码复用:

 横向抽取机制(AOP思想):

 AOP 思想: 基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,通过代理对象,调用增强功能的代码,从而对原有业务方法进行增强 !

 六、AOP实现原理:

1.jdk动态代理:

public interface UserDao {
    public void saveUser();
}
View Code
public class UserDaoImpl implements UserDao {

    @Override
    public void saveUser() {
        System.out.println("持久层:用户保存");
    }
}
View Code
@Test
    public void test1() {

        final UserDao userDao = new UserDaoImpl();
        // newProxyInstance的三个参数解释:
        // 参数1:代理类的类加载器,同目标类的类加载器
        // 参数2:代理类要实现的接口列表,同目标类实现的接口列表
        // 参数3:回调,是一个InvocationHandler接口的实现对象,当调用代理对象的方法时,执行的是回调中的invoke方法
        //proxy为代理对象
        UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
                userDao.getClass().getInterfaces(), new InvocationHandler() {

                    @Override
                    // 参数proxy:被代理的对象
                    // 参数method:执行的方法,代理对象执行哪个方法,method就是哪个方法
                    // 参数args:执行方法的参数
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("记录日志");
                        Object result = method.invoke(userDao, args);
                        return result;
                    }
                });
        //代理对象执行方法
        proxy.saveUser();
    }

 

运行结果:

在没有修改原有类的代码的情况下,对原有类的功能进行了增强

 2.cglib动态代理

在实际开发中,可能需要对没有实现接口的类增强,用JDK动态代理的方式就没法实现。采用Cglib动态代理可以对没有实现接口的类产生代理,实际上是生成了目标类的子类来增强。

推荐阅读