一、介绍
spring AOP:切面编程,是对类功能的增强。功能包括统一的权限控制、日志打印、异常处理等统一化处理;
二、实现方式
spring实现AOP的方式有两种,JDKProxy和CGLIB;spring是依照,如果类实现了接口,则选择JDKProxy,如果未实现接口,则选择CGLIB;
1、JDKProxy:适用于接口实现类,通过创建代理类,同样实现目标类的接口,以此来增强目标类的功能。
1)IUserOperation接口
package com.caocao; /** * Created by xuhui on 2019/10/8 */ public interface IUserOperation { String getUserName(String userId); }
2)UserOperationImpl接口实现类
package com.caocao; /** * 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.caocao; 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.caocao.IUserOperation.getUserName(java.lang.String)], args = [[Ljava.lang.Object;@23ab930d] userId = [333]
2、CGLIB:适用于所有类,通过创建目标类的子类,来增强目标类的功能。
1)CGLIB实现
package com.caocao; 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.caocao.UserOperation.getUserName(java.lang.String)], objects = [[Ljava.lang.Object;@61baa894] userId = [333]