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() {
@Override
public 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() {
@Override
public 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 {
@Override
public void myProxy() {
log.error("proxy");
}
}
运行结果
3.agent
这种方式会在类加载时增强,也不依赖于springboot,需要加入相关的jvm参数,会在类中加入增强的方法,通过this的方式调用