package J20250807;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author WanJl
 * @version 1.0
 * @title GetterSetterProxy
 * @description 使用CGLIB动态代理实现自动生成get和set方法
 * @create 2025/8/7
 */
public class GetterSetterProxy implements MethodInterceptor {
    //被代理的目标对象
    private Object target;

    /**
     * 拦截器方法，实现动态生成的getter和setter
     *
     * @param o
     * @param method
     * @param objects
     * @param methodProxy
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //获取到方法名
        String methodName = method.getName();
        //处理getter方法
        if (methodName.startsWith("get")&&method.getParameterCount()==0){
            //返回处理getter的方法
            return handelGetter(methodName);
        }
        //处理setter方法
        if (methodName.startsWith("set")&&method.getParameterCount()==1){
            //返回处理setter的方法
            return handelSetter(methodName,objects[0]);
        }
        //既不是get也不是set，就执行
        return methodProxy.invoke(o,objects);
    }

    /**
     * 处理set方法
     * @param methodName
     * @param value
     * @return
     */
    private Object handelSetter(String methodName, Object value) throws Exception {
        String fieldName=Character.toLowerCase(methodName.charAt(3))+methodName.substring(4);
        Field field = target.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(target,value);
        return null;
    }

    /**
     * 处理get方法
     * @param methodName
     * @return
     */
    private Object handelGetter(String methodName) throws Exception{
        //从方法名中提取属性名getName--->xxx
        //Character.toLowerCase 把字符转换为小写 把setName中大写的N转换为小写
        //methodName.substring(4)从索引值为4的位置开始截取，进行拼接 最终得到name
        String fieldName=Character.toLowerCase(methodName.charAt(3))+methodName.substring(4);
        Field field = target.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        return field.get(target);
    }


    /**
     * 创建代理对象
     *
     */
    public Object createProxy(Object target) {
        //检查是否被@GetterAndSetter注解进行修饰
        if (!target.getClass().isAnnotationPresent(GetterAndSetter.class)) {
            return target;
        }
        //使用CGLIB创建代理
        Enhancer enhancer = new Enhancer();
        //设置父类为目标类
        enhancer.setSuperclass(target.getClass());
        //设置回调对象
        enhancer.setCallback(this);
        //创建代理对象实例并且返回
        return  enhancer.create();
    }



}
