欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring面向切面编程(AOP)原理一之使用JDK实现动态代理

程序员文章站 2022-05-24 23:44:03
...
  1. 什么是面向切面编程?
    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
    简单的说,AOP就是在不破坏原有的类的基础上,生成一个代理类,可以在原来的类上进行增强,实现可以随时添加、取消添加的功能。
  2. 使用JDK中方法实现动态代理,必要条件:要有接口

创建一个接口

public interface UserDao {
   public void delete();
   public void save();
}

创建接口实现类

public class UserDaoImpl implements UserDao {

    @Override
    public void delete() {
        System.out.println("执行删除操作");
    }

    @Override
    public void save() {
        System.out.println("执行保存操作");
    }
}

创建代理对象

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


//使用JDK中的方法,实现动态代理,必须要有接口。。。
public class UserDaoJDKProxy {

    public UserDao createJDKProxy(UserDao userdao){
        UserDao UserDaoproxy =(UserDao) Proxy.newProxyInstance(userdao.getClass().getClassLoader(),
                userdao.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        /*//实现方法的动态增强
                        check();*/

                        //筛选某个方法进行增强
                        if("save".equals(method.getName())){
                            //实现方法的动态增强
                            check();
                            return (UserDao) method.invoke(userdao, args);
                        }

                        //返回的就是一个代理对象,代理对象执行方法的时候,就会进来回调
                        UserDao o = (UserDao) method.invoke(userdao, args);

                        return o;
                    }
                });
        return UserDaoproxy;
    }

    //定义需要被增强(代理)的方法
    public void check(){
        System.out.println("保存之前进行校验");
    }
}

编写测试方法

import org.junit.Test;

public class UserDaoTest {

    UserDao userdao = new UserDaoImpl();
    UserDaoJDKProxy userDaoJDKProxy = new UserDaoJDKProxy();

    @Test
    public void test(){
        //创建一个代理对象
        UserDao jdkProxy = userDaoJDKProxy.createJDKProxy(userdao);
        //代理对象调用方法,到创建的地方回调
        jdkProxy.delete();
        jdkProxy.save();
    }


}

运行结果

执行删除操作
保存之前进行校验
执行保存操作

Process finished with exit code 0

可以看到已经实现了对save()方法实现了增强,这就是动态代理的过程。
使用JDK创建代理对象,就是利用其中的反射机制,在原对象调用方法的时候,会到代理对象中进行方法的回调。
但是必须要有接口的存在,就是面向接口编程。