Spring框架的AOP实现(JDK+CGLIB)

AOP的底层采用了代理技术,代理技术提供了两种,一种是JDK动态代理,另一种是CGLIB动态代理。

基于JDK的动态代理:必须是面向接口,只有实现了具体的接口的类才能生成代理对象。
基于CGLIB的动态代理:对于没有实现了接口的类,也可以生成代理,生成这个类的子类方式。
一般如果实现接口,使用JDK动态代理完成AOP。没有实现接口,使用CGLIB动态代理实现AOP。

JDK动态代理的实现

UserDao,UserDaoImpl:

package com.spring.demo06;

public interface UserDao {
    
    public void save();
    
    public void update();

}
View Code
package com.spring.demo06;

public class UserDaoImpl implements UserDao{

    @Override
    public void save() {
        System.out.println("保存数据库。。。");
    }

    @Override
    public void update() {
        System.out.println("更新数据库。。。");
    }

}
View Code

JDK动态代理的工具类:

package com.spring.demo06;

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

/*
 * 使用JDK的方式生成代理对象
 */
public class MyProxyUtils {
    
    public static UserDao getProxy( UserDao userDao) {
        //使用Proxy类型生成一个代理对象
        UserDao proxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
            
            //代理对象的方法一执行,invoke中的方法就执行一次
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //如果save方法添加记录日志功能
                if("save".equals(method.getName())) {
                    System.out.println("记录日志。。。。");
                }
                System.out.println("代理对象。。。。");
                //让UserDaoImpl中的save或者update方法正常执行
                return method.invoke(userDao, args);
            }
        });
        //返回代理对象
        return proxy;
    }
}
View Code

测试:

package com.spring.demo06;

import org.junit.Test;

public class TestAOP {
    
    @Test
    public void run() {
        //目标对象
        UserDao userDao = new UserDaoImpl();
        userDao.save();
        userDao.update();
        
        System.out.println("================================");
        //使用工具类获取代理对象
        UserDao proxy = MyProxyUtils.getProxy(userDao);
        //调用代理对象的方法
        proxy.save();
        proxy.update();
        
    }
}
View Code

运行结果:

CGLIB动态代理的实现

UserDaoImpl:

package com.spring.demo07;

public class UserDaoImpl{

    public void save() {
        System.out.println("保存数据库。。。");
    }
    public void update() {
        System.out.println("更新数据库。。。");
    }

}
View Code

动态代理工具类:

package com.spring.demo07;

import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/*
 * 使用CGLIB的方式生成代理对象
 */
public class MyCglibUtils {
    
    public static UserDaoImpl getProxy() {
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(UserDaoImpl.class);
        //设置回调函数
        enhancer.setCallback(new MethodInterceptor() {
            //代理对象的方法执行,回调函数就会执行
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                System.out.println("CGLIB代理对象");
                if("save".equals(method.getName())) {
                    System.err.println("记录日志。。。。");
                }
                //正常执行
                return methodProxy.invokeSuper(obj, args);
            }
        });
        
        //生成代理对象
        UserDaoImpl proxy = (UserDaoImpl)enhancer.create();
        return proxy;
    }
}
View Code

测试:

package com.spring.demo07;

import org.junit.Test;

public class TestAOP {
    
    @Test
    public void run() {
        //目标对象
        UserDaoImpl userDao = new UserDaoImpl();
        userDao.save();
        userDao.update();
        
        System.out.println("================================");
        //使用CGLIB的方式生成代理对象
        UserDaoImpl proxy = MyCglibUtils.getProxy();
        //调用代理对象的方法
        proxy.save();
        proxy.update();
        
    }
}
View Code

运行结果:

原文地址:https://www.cnblogs.com/jumpkin1122/p/11624132.html