zoukankan      html  css  js  c++  java
  • 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

    运行结果:

  • 相关阅读:
    流媒体技术原理及播放方式(浅显易懂)
    实时音视频技术难点及解决方案
    流媒体技术简介
    DSP广告系统架构及关键技术解析(转)
    大型网站架构 图片服务器分离
    大话铁道部12306订票系统云架构
    技术揭秘12306改造(一):尖峰日PV值297亿下可每秒出票1032张
    12306火车票预定系统的需求分析
    PowerDesigner16.5 使用遇到的问题
    Ubuntu不输入密码执行sudo命令方法介绍
  • 原文地址:https://www.cnblogs.com/jumpkin1122/p/11624132.html
Copyright © 2011-2022 走看看