Spring的AOP原理总结

33 篇文章 0 订阅
11 篇文章 0 订阅

1、AOP 概述
AOP概述

AOP为Aspect Oriented Programming的缩写。意为面向切面编程。通过预编译方式和老实巴交行期动态代理实现程序

功能的统一维护的一种技术。AOP是OOP的延续、AOP:面向切面编程。AOP是OOP的扩展和延伸,解决OOP开发遇到问题。

AOP作用

在不修改源代码的情况下、可以实现功能的增强

传统代码是纵向体系代码复用、

AOP是横向抽取机制、基于代理思想、对原来目标对象、创建代理对象、在不修改原对象代码情况下、通过对代理对象、

调用增强功能的代码、从而对原有业务方法进行增强

AOP应用场景

场景一:记录日志

场景二:监控方法运行时间

场景三:权限抑制

场景四:缓存优化(第一调用查询数据库、将查询结果放入内存对象、第二次调用、直接从内存对象返回、不需要查询数据库)

场景五:事务管理(调用方法前开启事务、调用方法后提交关闭事务)

AOP原理

Spring中AOP有二种实现方式:

(1)、JDK动态代理 、只能对实现了接口的类产生代理。

(2)、Cglib动态代理、(类似于Javassist第三方代理技术):对没有实现接口的类产生代理对象。生成子类对象

2、Spring的AOP底层实现
(1)、JDK动态代理

UserDao.java接口
 

package com.day03.dao;
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:48 2018/11/11
 */
public interface UserDao {
    public abstract void save();
    public abstract void delete();
    public abstract void update();
    public abstract void select();
}
//UserDaoImpl.java实现类
package com.day03.dao.Impl;
 
import com.day03.dao.UserDao;
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:48 2018/11/11
 */
public class UserDaoImpl implements UserDao {
 
    @Override
    public void save() {
        System.out.println("save方法。。。。。。。。。。。");
    }
 
    @Override
    public void delete() {
        System.out.println("delete方法。。。。。。。。。。。");
    }
 
    @Override
    public void update() {
        System.out.println("update......................");
    }
 
    @Override
    public void select() {
        System.out.println("select...........................");
    }
}

代理类:TestProxy.java

package com.day03.test;
import com.day03.dao.UserDao;
import org.junit.Test;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;
import java.lang.reflect.Method;
 
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 11:47 2018/11/11
 */
public class TestProxy implements InvocationHandler {
    private UserDao userDao;
 
    public TestProxy(UserDao userDao) {
        this.userDao = userDao;
    }
 
    @Test
    public UserDao createProxy(){
        UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(),this);
        return proxy;
    }
    //回调方法
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        if ("save".equals(method.getName())){
            //增强
            System.out.println("增强权限。。。。。");
            return method.invoke(userDao,objects);
        }
        return method.invoke(userDao,objects);
    }
}

testDemo.java测试类

package com.day03.test;
 
import com.day03.dao.Impl.UserDaoImpl;
import com.day03.dao.UserDao;
import org.junit.Test;
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:51 2018/11/11
 */
public class TestDemo {
    @Test
    public void test1() {
        UserDao userDao = new UserDaoImpl();
        UserDao proxy = new TestProxy(userDao).createProxy();
        proxy.save();
        //userDao.save();
        proxy.delete();
        proxy.update();
        proxy.select();
    }
}

(2)、Cglib动态代理

UserDao.java接口

package com.day03.dao;
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:48 2018/11/11
 */
public interface UserDao {
    public abstract void save();
    public abstract void delete();
    public abstract void update();
    public abstract void select();
}


//
UserDaoImpl.java实现类

package com.day03.dao.Impl;
 
import com.day03.dao.UserDao;
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:48 2018/11/11
 */
public class UserDaoImpl implements UserDao {
 
    @Override
    public void save() {
        System.out.println("save方法。。。。。。。。。。。");
    }
 
    @Override
    public void delete() {
        System.out.println("delete方法。。。。。。。。。。。");
    }
 
    @Override
    public void update() {
        System.out.println("update......................");
    }
 
    @Override
    public void select() {
        System.out.println("select...........................");
    }
}

//
CglibProxy.java动态代理

package com.day03.test;
 
import com.day03.dao.UserDao;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
 
import java.lang.reflect.Method;
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 14:57 2018/11/12
 */
public class CglibProxy implements MethodInterceptor {
    private UserDao userDao;
 
    public CglibProxy(UserDao userDao) {
        this.userDao = userDao;
    }
 
    public UserDao createProxy(){
        //1、创建cglib的核心类对象
        Enhancer enhancer = new Enhancer();
        //2、设置父类
        enhancer.setSuperclass(userDao.getClass());
        //3、设置回调(类似InvocationHandler对象)
        enhancer.setCallback(this);
        //4、创建代理对象
        UserDao proxy = (UserDao) enhancer.create();
        return proxy;
    }
 
    @Override
    public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //判断方法是否为save;
        if ("save".equals(method.getName())){
            //增强
            System.out.println("权限核验。。。。。。。。。。。");
 
            return methodProxy.invokeSuper(proxy,objects);
        }
        return methodProxy.invokeSuper(proxy,objects);
    }
}

//
TestDemo.java测试类

package com.day03.test;
 
import com.day03.dao.Impl.UserDaoImpl;
import com.day03.dao.UserDao;
import org.junit.Test;
 
/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 21:51 2018/11/11
 */
public class TestDemo {
    @Test
    public void test1() {
        UserDao userDao = new UserDaoImpl();
        UserDao proxy = new CglibProxy(userDao).createProxy();
        proxy.save();
        //userDao.save();
        proxy.delete();
        proxy.update();
        proxy.select();
    }
}

 

 

3、AOP相关术语
Joinpoint (连接点)

连接点是指那些被拦截到的点、在spring中、这些点指的是方法、spring只支持方法类型的连接点

Pointcut(切入点)

指的是我们要对哪些Joinpoint进行拦截

Advice(通知/增强)

通知是指拦截到Joinpoint之后所要做的事情就是通知、通知分为前置通知、后置通知、异常通知、最终通知、环绕通知(切面要完成的功能)

Introduction(引介)

引介是一种特殊的通知、在不修改代码的前提下、Introduction可以在运行期为类动态地添加一些方法或Field

Target(目标对象)

代理的目标对象

Weaving(织入)

是指把增强应用到目标对象来创建新的代理对象的过程、spring采用动态代理织入、而Asp

Proxy(代理)

一个类被AOP织入增强后、就产生一个结果代理类

Aspect(切面)

是切入红开和通知(引介)的结合

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOP(面向切面编程)的实现原理是基于动态代理技术。 在 Spring AOP 中,主要使用了两种类型的代理:JDK 动态代理和 CGLIB 代理。 1. JDK 动态代理: - 当目标类实现了至少一个接口时,Spring AOP 使用 JDK 动态代理。 - JDK 动态代理通过 Java 的反射机制在运行时动态创建代理对象。 - 在运行时,Spring AOP 根据目标类实现的接口信息,生成一个继承了 Proxy 类并实现了目标接口的代理类。 - 当目标方法被调用时,代理类会通过反射机制调用 InvocationHandler 接口的 invoke 方法,并在该方法中执行切面逻辑。 2. CGLIB 代理: - 当目标类没有实现任何接口时,Spring AOP 使用 CGLIB 代理。 - CGLIB 是一个强大的第三方库,能够在运行时生成目标类的子类来实现代理逻辑。 - 在运行时,Spring AOP 使用 CGLIB 创建一个目标类的子类,并在子类中覆盖目标方法,加入切面逻辑。 - 当目标方法被调用时,代理对象会直接调用子类中的方法,并执行切面逻辑。 Spring AOP 的核心是切面(Aspect)和连接点(Join Point)的概念: - 切面定义了要在特定连接点执行的切面逻辑。 - 连接点是在应用程序执行过程中可以应用切面的点,如方法调用、方法执行前后、异常处理等。 Spring AOP 通过切点(Pointcut)来确定连接点,将切面逻辑织入到切点所指定的连接点上,从而实现对目标对象的增强。 总结起来,Spring AOP 的实现原理是利用动态代理技术,在运行时动态生成代理对象,并将切面逻辑织入到目标对象的方法中。 希望能清晰地回答你的问题!如果还有疑问,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值