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

Posted jumpkin1122

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

运行结果:

技术图片

 

以上是关于Spring框架的AOP实现(JDK+CGLIB)的主要内容,如果未能解决你的问题,请参考以下文章

AOP的底层实现-CGLIB动态代理和JDK动态代理

基于Spring AOP的JDK动态代理和CGLIB代理

spring aop原理 JDK动态代理和CGLIB动态代理

Spring——AOP实现原理(基于JDK和CGLIB)

Spring——AOP实现原理(基于JDK和CGLIB)

spring的AOP动态代理--JDK代理和CGLIB代理