<Spring>AOP——JDK动态代理实现-5

一、AOP的概念

1、AOP(Aspect Oriented Programming),面向切面编程,利用AOP可以对业务逻辑各部分进行隔离,从而降低耦合度

2、通俗地说就是,AOP可以不通过修改源代码的方式在主干功能里添加新功能

例如
在这里插入图片描述

这里如果要在登录功能的基础上,实现登录用户身份的判断,原始方式就是修改源代码,通过if语句进行判断,使用AOP就可以在不修改源代码的条件下添加判断功能的模块

二、AOP底层原理

1、AOP底层使用动态代理

动态代理有两种情况

(1)有接口,使用JDK动态代理
(2)没有接口,使用CGLIB动态代理

第一种 有接口情况,使用JDK动态代理

那么就是创建接口实现类代理对象,增强类的方法

在这里,接口实现类是UserDaoImpl,类的方法是login
在这里插入图片描述

第二种 没有接口情况,使用CGLIB动态代理

通过创建子类的代理对象,增强类的方法

在这里插入图片描述

三、AOP(JDK动态代理)

1、使用JDK动态代理,使用Proxy类里面的方法创建代理对象

Proxy类
在这里插入图片描述

类Proxy的构造方法和普通方法
在这里插入图片描述

接口IncocationHandler
在这里插入图片描述

(1)调用newProxyInstance方法

在这里插入图片描述
方法的三个参数:
官方文档:

参数:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
返回:
一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口


个人理解

第一个参数,类加载器
第二个参数,增强方法所在的类,这个类实现了接口,支持多个接口
第三个参数,InvocationHandler,这是一个接口,将创建一个类实现这个接口,然后实现需要增强的功能

2、编写JDK动态代理代码

(1)创建接口,定义方法

package com.pencil.spring5;

public interface UserDao {
    public int add(int a,int b);
    public String update(String str);
}

(2)创建接口实现类,实现方法

package com.pencil.spring5;

public class UserDaoImpl implements UserDao{
    @Override
    public int add(int a, int b) {
        System.out.println("UserDao:add方法调用...");
        return a+b;
    }

    @Override
    public String update(String str) {
        System.out.println("UserDao:update方法调用...");
        return str;
    }
}

(3)使用Proxy类创建接口代理对象

package com.pencil.spring5;

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

public class JDKProxy {
    public static void main(String[] args) {
        //创建接口实现类代理对象
        //newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
        Class[] interfaces={UserDao.class};
        UserDaoImpl userDao=new UserDaoImpl();
        UserDao res= (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao));
        int ans=res.add(1,2);
        System.out.println("answer:"+ans);
    }
}


//创建代理对象代码,即方法newProxyInstance的第三个参数

class UserDaoProxy implements InvocationHandler
{
    //1、把需要创建代理对象的类传进来
    private UserDaoImpl userDao;   //如果希望通用使用,可以用Object代替UserDaoImpl
    public UserDaoProxy(UserDaoImpl userDao)
    {
        this.userDao=userDao;
    }
    //增强的逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法之前
        System.out.println("方法之前执行..."+method.getName()+":传递的参数...."+ Arrays.toString(args));

        //被增强的方法执行
        Object obj= method.invoke(userDao,args);

        //方法之后
        System.out.println("方法之后执行..."+userDao);
        return obj;
    }


}

运行结果

在这里插入图片描述

main函数中主要是为了创建接口的代理类实例

创建接口的代理类实例时,使用到方法newProxyInstance,而方法的第三个参数InvocationHandler h,这个是指派方法调用的调用处理程序 ,而InvocationHandler h是一个接口,因此创建一个类来实现它,那么就是实现其invoke()方法。

实现invoke方法,那么就要把需要创建代理对象的类传进来,因此创建一个有参构造函数,将类传进来。然后在invoke方法中实现需要增强的方法

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值