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]

 

posted @ 2019-10-08 17:15  JokerPig  阅读(482)  评论(0编辑  收藏  举报