为没有实现接口的类提供代理
更好的性能
原理:动态生成需要代理的子类,子类重写代理类的非final方法。子类中采用方法拦截的奇数拦截所有父类的方法的调用,顺势织入横切逻辑。
底层:使用ASM字节码处理框架。
缺点:无法代理fianl方法。
Spring AOP
.NET.sf.cglib.core: 底层字节码处理类,他们大部分与ASM有关系。
net.sf.cglib.transform: 编译期或运行期类和类文件的转换
net.sf.cglib.proxy: 实现创建代理和方法拦截器的类
net.sf.cglib.reflect: 实现快速反射和C#风格代理的类
net.sf.cglib.util: 集合排序等工具类
net.sf.cglib.beans: JAVABean相关的工具类
package com.cclu.cglibproxy;
import java.util.HashMap;
import java.util.Map;
/**
* @author ChangCheng Lu
* @date 2023/8/20 15:59
*/
public class UserService {
private static final Map<String, String> nameMap;
private static final Map<String, String> addressMap;
static {
nameMap = new HashMap<>(3);
nameMap.put("1001", "木子");
nameMap.put("1002", "小一");
nameMap.put("1003", "阿同");
addressMap = new HashMap<>(3);
addressMap.put("1001", "涟水");
addressMap.put("1002", "淮安");
addressMap.put("1003", "上海");
}
public String getUserNameById(String userId) {
return nameMap.get(userId);
}
public String getAddressById(String userId) {
return addressMap.get(userId);
}
}
package com.cclu.cglibproxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @author ChangCheng Lu
* @date 2023/8/20 16:04
*/
public class LogInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("方法调用前...");
Object res = methodProxy.invokeSuper(o, objects);
System.out.println("方法调用后:"+res);
return res;
}
}
package com.cclu.cglibproxy;
import net.sf.cglib.proxy.Enhancer;
/**
* @author ChangCheng Lu
* @date 2023/8/20 16:10
*/
public class Client {
public static void mAIn(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback(new LogInterceptor());
UserService userService = (UserService) enhancer.create();
userService.getUserNameById("1001");
userService.getAddressById("1003");
}
}
package com.cclu.cglibproxy;
import java.util.HashMap;
import java.util.Map;
/**
* @author ChangCheng Lu
* @date 2023/8/20 15:59
*/
public class UserService {
private static final Map<String, String> nameMap;
private static final Map<String, String> addressMap;
static {
nameMap = new HashMap<>(3);
nameMap.put("1001", "木子");
nameMap.put("1002", "小一");
nameMap.put("1003", "阿同");
addressMap = new HashMap<>(3);
addressMap.put("1001", "苏州");
addressMap.put("1002", "淮安");
addressMap.put("1003", "上海");
}
public String getUserNameById(String userId) {
return nameMap.get(userId);
}
public String getAddressById(String userId) {
return addressMap.get(userId);
}
}
package com.cclu.cglibproxy;
import net.sf.cglib.proxy.CallbackFilter;
import java.lang.reflect.Method;
/**
* @author ChangCheng Lu
* @date 2023/8/20 16:35
*/
public class LogInterceptorFilter implements CallbackFilter {
@Override
public int accept(Method method) {
if (method.getName().equals("getUserNameById")) {
System.out.println("是不是木子?");
return 1;
} else if (method.getName().equals("getAddressById")) {
System.out.println("是不是阿同?");
return 2;
}
return 0;
}
}
package com.cclu.cglibproxy;
import net.sf.cglib.proxy.FixedValue;
/**
* @author ChangCheng Lu
* @date 2023/8/20 17:44
*/
public class TargetResultFixed implements FixedValue {
@Override
public Object loadObject() throws Exception {
System.out.println("锁定结果");
Object obj = "苏州";
return obj;
}
}
package com.cclu.cglibproxy;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.NoOp;
import org.junit.Test;
/**
* @author ChangCheng Lu
* @date 2023/8/20 17:32
*/
public class ProxyTest {
@Test
public void filterTest() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallbackFilter(new LogInterceptorFilter());
enhancer.setCallbacks(new Callback[]{NoOp.INSTANCE, new LogInterceptor(), new TargetResultFixed()});
UserService userService = (UserService) enhancer.create();
System.out.println(userService);
System.out.println(userService.getUserNameById("1001"));
System.out.println(userService.getAddressById("1003"));
}
}
https://www.runoob.com/w3cnote/cglibcode-generation-library-intro.html