java的aop可以通过三种方式来实现
1.使用ajc编译的插件来完成增强
这种方法会直接修改编译完成的class文件,不需要依赖springboot
2.动态代理proxy
2.1cglib
可以代理接口,方法等,这种方式代理类是目标类的子类,要求目标类不能是final修饰,若方法为final则不能增强,MethodProxy proxy可以不使用反射,优化效率
package com.ai.hdl.system.study.spring;import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;@Slf4j
public class MyProxy1 {public static void main(String[] args) {IMyProxyImpl1 iMyProxyImpl1 = new IMyProxyImpl1();IMyProxyImpl1 before = (IMyProxyImpl1) Enhancer.create(IMyProxyImpl1.class , new MethodInterceptor() {@Overridepublic Object intercept(Object obj , Method method , Object[] args , MethodProxy proxy) throws Throwable {System.out.println("before");Object invoke = method.invoke(iMyProxyImpl1 , args);return invoke;}});before.myProxy();}
}
@Slf4j
class IMyProxyImpl1 {public void myProxy() {log.error("proxy1");}
}
运行结果
2.2jdk
这种方式只能通过接口代理其他方法,这种方式代理类也会继承接口
package com.ai.hdl.system.study.spring;import lombok.extern.slf4j.Slf4j;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;@Slf4j
public class MyProxy {public static void main(String[] args) {IMyProxyImpl myProxy = new IMyProxyImpl();ClassLoader classLoader = IMyProxy.class.getClassLoader();IMyProxy before = (IMyProxy) Proxy.newProxyInstance(classLoader , new Class[]{IMyProxy.class} , new InvocationHandler() {@Overridepublic Object invoke(Object proxy , Method method , Object[] args) throws Throwable {log.error("before");Object invoke = method.invoke(myProxy,args);return invoke;
// return null;}});before.myProxy();}
}
interface IMyProxy {void myProxy();}
@Slf4j
class IMyProxyImpl implements IMyProxy {@Overridepublic void myProxy() {log.error("proxy");}
}
运行结果
3.agent
这种方式会在类加载时增强,也不依赖于springboot,需要加入相关的jvm参数,会在类中加入增强的方法,通过this的方式调用