zoukankan      html  css  js  c++  java
  • spring AOP原理解析

    一、介绍

    spring AOP:切面编程,是对类功能的增强。功能包括统一的权限控制、日志打印、异常处理等统一化处理;

    二、实现方式

    spring实现AOP的方式有两种,JDKProxy和CGLIB;spring是依照,如果类实现了接口,则选择JDKProxy,如果未实现接口,则选择CGLIB;

    1、JDKProxy:适用于接口实现类,通过创建代理类,同样实现目标类的接口,以此来增强目标类的功能。

    1)IUserOperation接口

    package com.xuhui;
    
    /**
     * Created by xuhui on 2019/10/8  
     */
    public interface IUserOperation {
        String getUserName(String userId);
    }

    2)UserOperationImpl接口实现类

    package com.xuhui;
    
    /**
     * Created by xuhui on 2019/10/8  
     */
    public class UserOperationImpl implements IUserOperation {
        @Override
        public String getUserName(String userId) {
            System.out.println("userId = [" + userId + "]");
            return userId + "_name";
        }
    }

    3)JDKProxy实现

    package com.xuhui;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * Created by xuhui on 2019/10/8  
     */
    public class UserProxy {
        public static void main(String[] args) {
            jdkProxy();
        }
    
        public static void jdkProxy() {
            IUserOperation userOperation = new UserOperationImpl();
            IUserOperation proxy = (IUserOperation) Proxy.newProxyInstance(userOperation.getClass().getClassLoader(),
                    userOperation.getClass().getInterfaces(), new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("method = [" + method + "], args = [" + args + "]");
                            return method.invoke(userOperation, args);
                        }
                    });
            proxy.getUserName("333");
        }
    
    }

    4)输出结果

    method = [public abstract java.lang.String com.xuhui.IUserOperation.getUserName(java.lang.String)], args = [[Ljava.lang.Object;@23ab930d]
    userId = [333]

    2、CGLIB:适用于所有类,通过创建目标类的子类,来增强目标类的功能。

    1)CGLIB实现

    package com.xuhui;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    /**
     * Created by xuhui on 2019/10/8  
     */
    public class UserProxy {
        public static void main(String[] args) {
            cglib();
        }
    
        public static void cglib() {
            UserOperation userOperation = new UserOperationImpl();
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(userOperation.getClass());
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    System.out.println("method = [" + method + "], objects = [" + objects + "]");
                    return method.invoke(userOperation, objects);
                }
            });
            UserOperation proxy = (UserOperation) enhancer.create();
            proxy.getUserName("333");
        }
    }

    2)结果输出

    method = [public java.lang.String com.xuhui.UserOperation.getUserName(java.lang.String)], objects = [[Ljava.lang.Object;@61baa894]
    userId = [333]
  • 相关阅读:
    ADO连接access和oracle的一个区别
    我的大救星——Oracle APEX 快速Web开发(鼠标点点即可开发出专业级Web应用)
    Sql Server 2008 R2 error:40 错误处理
    我的第一个WPF程序
    开源社会网络分析工具NodeXL介绍
    JavaScript学习笔记1之基础知识点
    JavaScript学习笔记6 之经典神坑题整理
    JavaScript学习笔记2之Tab切换
    变量声明和函数声明会提升到当前作用域顶部
    JavaScript学习笔记5 之 计时器 & scroll、offset、client系列属性 & 图片无缝滚动
  • 原文地址:https://www.cnblogs.com/jave1ove/p/11636632.html
Copyright © 2011-2022 走看看