JavaEE SpringAOP的两种实现方式


AOP的全称是’‘Aspect Oriented Programming’’,即 面向切面编程,它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑的时候可以专心于核心业务,从而提高开发效率。

应用场景

需要在具体的业务方法前后,执行统一业务逻辑处理的代码
在这里插入图片描述

Spring框架实现AOP的方式

Spring框架代理的时候,会根据是否实现接口来决定使用哪个动态代理

1.JDK的实现方式

Proxy.newProxyInstance() 结合InvocationHandler() 被代理类需要实现某一个接口,通过接口来使用
原理:
java文件在编译期间编译为class字节码,运行时加载对应类到方法区。
1、运行期,根据被代理类,生成代理类的字节码,将被代理类装到代理类中
2、被代理类方法执行前后,插入统一处理逻辑
3、使用的时候,使用代理类,不使用被代理类(代理类已经包裹了被代理类)

在这里插入图片描述

在 com.mengma.jdk 包下创建一个名为 MyBeanFactory 的类,在该类中使用 java.lang.reflect.Proxy 实现 JDK 动态代理


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.mengma.dao.CustomerDao;
import com.mengma.dao.CustomerDaoImpl;
public class MyBeanFactory {
    public static CustomerDao getBean() {
        // 准备目标类
        final CustomerDao customerDao = new CustomerDaoImpl();
        // 创建切面类实例
        final MyAspect myAspect = new MyAspect();
        // 使用代理类,进行增强
        return (CustomerDao) Proxy.newProxyInstance(
                MyBeanFactory.class.getClassLoader(),
                new Class[] { CustomerDao.class }, new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,
                            Object[] args) throws Throwable {
                        myAspect.myBefore(); // 前增强
                        Object obj = method.invoke(customerDao, args);
                        myAspect.myAfter(); // 后增强
                        return obj;
                    }
                });
    }
}


上述代码中,定义了一个静态的 getBean() 方法,这里模拟 Spring 框架的 IoC 思想,通过调用 getBean() 方法创建实例,第 14 行代码创建了 customerDao 实例。

第 16 行代码创建的切面类实例用于调用切面类中相应的方法;第 1826 行就是使用代理类对创建的实例 customerDao 中的方法进行增强的代码,其中 Proxy 的 newProxyInstance() 方法的第一个参数是当前类的类加载器,第二参数是所创建实例的实现类的接口,第三个参数就是需要增强的方法。

在目标类方法执行的前后,分别执行切面类中的 myBefore() 方法和 myAfter() 方法。

2.CGLIB的实现方式

MethodInterceptor完成方法执行前后的业务逻辑插入,在通过ASM字节码技术,生成代理类的字节码
前置条件:被代理类不需要接口,但不能为final修饰


import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.mengma.dao.GoodsDao;
import com.mengma.jdk.MyAspect;
public class MyBeanFactory {
    public static GoodsDao getBean() {
        // 准备目标类
        final GoodsDao goodsDao = new GoodsDao();
        // 创建切面类实例
        final MyAspect myAspect = new MyAspect();
        // 生成代理类,CGLIB在运行时,生成指定对象的子类,增强
        Enhancer enhancer = new Enhancer();
        // 确定需要增强的类
        enhancer.setSuperclass(goodsDao.getClass());
        // 添加回调函数
        enhancer.setCallback(new MethodInterceptor() {
            // intercept 相当于 jdk invoke,前三个参数与 jdk invoke—致
            @Override
            public Object intercept(Object proxy, Method method, Object[] args,
                    MethodProxy methodProxy) throws Throwable {
                myAspect.myBefore(); // 前增强
                Object obj = method.invoke(goodsDao, args); // 目标方法执行
                myAspect.myAfter(); // 后增强
                return obj;
            }
        });
        // 创建代理类
        GoodsDao goodsDaoProxy = (GoodsDao) enhancer.create();
        return goodsDaoProxy;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值