java写框架、改底层等,"动态代理"必不可少
本人不怎么爱写博客,原因在于觉得浪费时间。 —
但是今天朋友内推我面试。这才意识到自己没有底子给别人看是莫大的后悔啊
不多说了,以后我发现什么新奇的东西、探索类的知识,跟大家分享出来
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtilsBean;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.util.ClassUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 代理对象忽略某些方法
*
* @author 草先生
*/
@Slf4j
public class MethodProxy<T> implements MethodInterceptor {
private T target;
private CallBack<T> callBack;
public MethodProxy(T proxyTarget) {
this.target = proxyTarget;
}
public T getProxyIgnoreSetMethodNames(String... ignoreMethodNames) {
this.callBack = (t, method, args) -> {
for (String ignoreMethodName : ignoreMethodNames) {
if (Objects.equals(ignoreMethodName.intern(), method.getName().intern())) {
return null;
}
}
return method.invoke(target, args);
};
return getT();
}
public T getProxyIgnoreSetMethod() {
// 忽略所有的set方法
PropertyDescriptor[] descriptors = BeanUtilsBean.getInstance().getPropertyUtils().getPropertyDescriptors(target);
List<String> ignoreMethodNames = Stream.of(descriptors)
.map(PropertyDescriptor::getWriteMethod)
.filter(Objects::nonNull)
.map(Method::getName)
.map(String::intern)
.collect(Collectors.toList());
this.callBack = (t, method, args) -> {
if (ignoreMethodNames.contains(method.getName().intern())) {
return null;
}
return method.invoke(target, args);
};
return getT();
}
public T getProxy(CallBack<T> callBack) {
this.callBack = callBack;
return getT();
}
private T getT() {
// 创建代理对象
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
// 如果针对class创建失败,则只针对接口创建代理
try {
//noinspection unchecked
return (T) enhancer.create();
} catch (Exception e) {
enhancer = new Enhancer();
Class<?>[] allInterfacesForClass = ClassUtils.getAllInterfaces(this.target);
enhancer.setInterfaces(allInterfacesForClass);
enhancer.setCallback(this);
//noinspection unchecked
return (T) enhancer.create();
}
}
@Override
public Object intercept(Object obj, Method method, Object[] args, org.springframework.cglib.proxy.MethodProxy proxy) throws Exception {
return callBack.call(target, method, args);
}
public interface CallBack<T> {
/**
* 代理拦截的方法,需要用户自己实现
*/
Object call(T target, Method method, Object[] args) throws Exception;
}
}