1-1-3 Java深度强化-反射与动态代理机制

59 阅读8分钟

🔍 Java反射与动态代理机制详解

一、反射机制(Reflection)

1.1 什么是反射?

反射是在运行时动态获取类的信息并操作类对象的能力。通过反射,我们可以在程序运行时:

  • 获取类的Class对象
  • 创建类的实例
  • 调用类的方法
  • 访问/修改类的字段
  • 获取类的注解信息

1.2 核心API详解

1.2.1 获取Class对象的四种方式
// 方式1:通过类名.class(最安全,编译器检查)
Class<String> clazz1 = String.class;

// 方式2:通过对象.getClass()
String str = "hello";
Class<? extends String> clazz2 = str.getClass();

// 方式3:通过Class.forName()(最常用,可配置)
Class<?> clazz3 = Class.forName("java.lang.String");

// 方式4:通过ClassLoader.loadClass()
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?> clazz4 = classLoader.loadClass("java.lang.String");
1.2.2 创建实例的三种方式
Class<?> clazz = Class.forName("com.example.User");

// 方式1:使用newInstance()(已废弃,Java 9+)
// User user1 = (User) clazz.newInstance();

// 方式2:使用Constructor.newInstance()(推荐)
Constructor<?> constructor = clazz.getConstructor();
User user2 = (User) constructor.newInstance();

// 方式3:带参数的构造器
Constructor<?> paramConstructor = clazz.getConstructor(String.class, int.class);
User user3 = (User) paramConstructor.newInstance("张三", 25);

1.3 字段(Field)操作

public class User {
    private String name;
    public int age;
    private static final String TAG = "User";
}

Class<User> clazz = User.class;

// 获取所有public字段(包括父类)
Field[] publicFields = clazz.getFields();

// 获取所有声明的字段(不包括父类)
Field[] declaredFields = clazz.getDeclaredFields();

// 获取特定字段
Field nameField = clazz.getDeclaredField("name");
Field ageField = clazz.getField("age");

// 设置访问权限(访问private字段需要)
nameField.setAccessible(true);

// 读取字段值
User user = new User("李四", 30);
String name = (String) nameField.get(user);  // "李四"

// 修改字段值
nameField.set(user, "王五");

1.4 方法(Method)操作

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    private int multiply(int a, int b) {
        return a * b;
    }
}

Class<Calculator> clazz = Calculator.class;

// 获取所有public方法(包括父类方法)
Method[] publicMethods = clazz.getMethods();

// 获取所有声明的方法
Method[] declaredMethods = clazz.getDeclaredMethods();

// 获取特定方法
Method addMethod = clazz.getMethod("add", int.class, int.class);
Method multiplyMethod = clazz.getDeclaredMethod("multiply", int.class, int.class);

// 调用方法
Calculator calc = new Calculator();
Object result = addMethod.invoke(calc, 10, 20);  // 30

// 调用私有方法
multiplyMethod.setAccessible(true);
Object multiplyResult = multiplyMethod.invoke(calc, 10, 20);  // 200

// 调用静态方法
Method staticMethod = clazz.getMethod("staticMethod");
staticMethod.invoke(null);  // 第一个参数为null表示静态方法

1.5 构造器(Constructor)操作

public class Person {
    private String name;
    
    public Person() {}
    
    private Person(String name) {
        this.name = name;
    }
}

Class<Person> clazz = Person.class;

// 获取所有public构造器
Constructor<?>[] publicConstructors = clazz.getConstructors();

// 获取所有构造器(包括private)
Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();

// 获取特定构造器
Constructor<Person> defaultConstructor = clazz.getConstructor();
Constructor<Person> privateConstructor = clazz.getDeclaredConstructor(String.class);

// 访问私有构造器
privateConstructor.setAccessible(true);
Person person = privateConstructor.newInstance("秘密人物");

1.6 反射性能优化技巧

// ❌ 错误的用法:每次调用都获取Method
for (int i = 0; i < 10000; i++) {
    Method method = clazz.getMethod("methodName");
    method.invoke(obj, args);
}

// ✅ 正确的用法:缓存Method
private static final Method CACHED_METHOD;

static {
    try {
        CACHED_METHOD = TargetClass.class.getMethod("methodName");
        CACHED_METHOD.setAccessible(true);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

// 使用时直接调用
CACHED_METHOD.invoke(obj, args);

二、动态代理(Dynamic Proxy)

2.1 什么是动态代理?

动态代理是在运行时创建代理类和代理对象的机制,主要用于AOP(面向切面编程)

2.2 核心接口和类

// InvocationHandler - 代理调用的处理器接口
public interface InvocationHandler {
    Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

// Proxy - 创建代理对象的工厂类
public class Proxy {
    public static Object newProxyInstance(
        ClassLoader loader,
        Class<?>[] interfaces,
        InvocationHandler h
    );
}

2.3 动态代理实现步骤

2.3.1 定义接口和实现类
// 1. 定义接口
public interface IUserService {
    void addUser(String username);
    void deleteUser(String username);
    String getUser(String username);
}

// 2. 实现类
public class UserServiceImpl implements IUserService {
    @Override
    public void addUser(String username) {
        System.out.println("添加用户: " + username);
    }
    
    @Override
    public void deleteUser(String username) {
        System.out.println("删除用户: " + username);
    }
    
    @Override
    public String getUser(String username) {
        return "用户信息: " + username;
    }
}
2.3.2 创建InvocationHandler
public class LogInvocationHandler implements InvocationHandler {
    private final Object target;  // 被代理的对象
    
    public LogInvocationHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 前置增强
        long startTime = System.currentTimeMillis();
        System.out.println("方法调用开始: " + method.getName());
        System.out.println("参数: " + Arrays.toString(args));
        
        try {
            // 调用原始方法
            Object result = method.invoke(target, args);
            
            // 后置增强
            System.out.println("方法调用结束: " + method.getName());
            System.out.println("返回值: " + result);
            System.out.println("耗时: " + (System.currentTimeMillis() - startTime) + "ms");
            
            return result;
        } catch (Exception e) {
            // 异常增强
            System.err.println("方法调用异常: " + method.getName());
            System.err.println("异常信息: " + e.getMessage());
            throw e;
        }
    }
}
2.3.3 创建代理对象
public class ProxyFactory {
    public static <T> T createProxy(T target, Class<T> interfaceClass) {
        // 1. 创建InvocationHandler
        InvocationHandler handler = new LogInvocationHandler(target);
        
        // 2. 创建代理对象
        return (T) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),  // 类加载器
            new Class<?>[]{interfaceClass},      // 代理接口
            handler                              // InvocationHandler
        );
    }
}

// 使用示例
IUserService userService = new UserServiceImpl();
IUserService proxy = ProxyFactory.createProxy(userService, IUserService.class);

// 调用代理方法
proxy.addUser("张三");
// 输出:
// 方法调用开始: addUser
// 参数: [张三]
// 添加用户: 张三
// 方法调用结束: addUser
// 返回值: null
// 耗时: 5ms

2.4 动态代理源码分析

// Proxy.newProxyInstance()的核心逻辑(简化版):
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h) {
    
    // 1. 生成代理类的字节码
    byte[] proxyClassFile = generateProxyClass(interfaces);
    
    // 2. 定义代理类
    Class<?> proxyClass = defineClass0(loader, proxyClassFile);
    
    // 3. 创建代理实例
    Constructor<?> cons = proxyClass.getConstructor(InvocationHandler.class);
    return cons.newInstance(h);
}

// 生成的代理类大致结构如下:
public final class $Proxy0 extends Proxy implements IUserService {
    private static Method m1;  // addUser方法
    private static Method m2;  // deleteUser方法
    private static Method m3;  // getUser方法
    
    static {
        try {
            m1 = Class.forName("IUserService").getMethod("addUser", String.class);
            m2 = Class.forName("IUserService").getMethod("deleteUser", String.class);
            m3 = Class.forName("IUserService").getMethod("getUser", String.class);
        } catch (Exception e) {
            throw new Error(e);
        }
    }
    
    public $Proxy0(InvocationHandler h) {
        super(h);
    }
    
    @Override
    public void addUser(String username) {
        try {
            h.invoke(this, m1, new Object[]{username});
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
    
    // 其他方法类似...
}

2.5 动态代理的限制和解决方案

限制1:只能代理接口
// ❌ 不能直接代理类
UserServiceImpl target = new UserServiceImpl();
// UserServiceImpl proxy = (UserServiceImpl) Proxy.newProxyInstance(...); // 编译错误

// ✅ 解决方案:使用CGLIB或ByteBuddy
public class CglibProxyFactory {
    public static <T> T createProxy(T target) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, 
                                  MethodProxy proxy) throws Throwable {
                System.out.println("前置增强");
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("后置增强");
                return result;
            }
        });
        return (T) enhancer.create();
    }
}
限制2:性能问题
// 性能优化方案:缓存代理类
public class ProxyCache {
    private static final Map<String, Class<?>> PROXY_CLASS_CACHE = new ConcurrentHashMap<>();
    
    public static Object createProxy(Object target, Class<?>[] interfaces, 
                                    InvocationHandler handler) {
        String cacheKey = generateCacheKey(interfaces);
        
        Class<?> proxyClass = PROXY_CLASS_CACHE.computeIfAbsent(cacheKey, key -> {
            return Proxy.getProxyClass(target.getClass().getClassLoader(), interfaces);
        });
        
        try {
            Constructor<?> constructor = proxyClass.getConstructor(InvocationHandler.class);
            return constructor.newInstance(handler);
        } catch (Exception e) {
            throw new RuntimeException("创建代理失败", e);
        }
    }
    
    private static String generateCacheKey(Class<?>[] interfaces) {
        return Arrays.stream(interfaces)
                     .map(Class::getName)
                     .sorted()
                     .collect(Collectors.joining(","));
    }
}

三、在Android Framework中的应用

3.1 Activity的反射实例化

// Android系统中Activity的创建过程
public Activity instantiateActivity(ClassLoader cl, String className, Intent intent) 
        throws Exception {
    // 1. 通过类名加载Class
    Class<?> clazz = cl.loadClass(className);
    
    // 2. 创建Activity实例
    Activity activity = (Activity) clazz.newInstance();
    
    // 3. 调用attach方法
    activity.attach(context, ...);
    
    return activity;
}

3.2 Binder机制的动态代理

// AIDL生成的代理类就是动态代理的应用
public interface IMyService extends IInterface {
    void doSomething();
}

// 系统生成的Stub和Proxy
public abstract class MyServiceStub extends Binder implements IMyService {
    // ... Stub实现
    
    // 客户端使用的Proxy类
    private static class Proxy implements IMyService {
        private IBinder mRemote;
        
        Proxy(IBinder remote) {
            mRemote = remote;
        }
        
        @Override
        public void doSomething() {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            try {
                data.writeInterfaceToken(DESCRIPTOR);
                // 通过Binder发送数据
                mRemote.transact(TRANSACTION_doSomething, data, reply, 0);
                reply.readException();
            } finally {
                data.recycle();
                reply.recycle();
            }
        }
    }
}

3.3 Hook技术的应用

// Hook Activity启动过程的示例
public class HookManager {
    
    public static void hookActivityManager() {
        try {
            // 1. 获取ActivityManagerNative的Class
            Class<?> amnClass = Class.forName("android.app.ActivityManagerNative");
            
            // 2. 获取gDefault字段
            Field gDefaultField = amnClass.getDeclaredField("gDefault");
            gDefaultField.setAccessible(true);
            Object gDefault = gDefaultField.get(null);
            
            // 3. 获取IActivityManager实例
            Class<?> singletonClass = Class.forName("android.util.Singleton");
            Field mInstanceField = singletonClass.getDeclaredField("mInstance");
            mInstanceField.setAccessible(true);
            Object rawIActivityManager = mInstanceField.get(gDefault);
            
            // 4. 创建代理对象
            Class<?> iActivityManagerInterface = Class.forName("android.app.IActivityManager");
            Object proxy = Proxy.newProxyInstance(
                Thread.currentThread().getContextClassLoader(),
                new Class<?>[] { iActivityManagerInterface },
                new IActivityManagerHandler(rawIActivityManager)
            );
            
            // 5. 替换原对象
            mInstanceField.set(gDefault, proxy);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    static class IActivityManagerHandler implements InvocationHandler {
        private Object mBase;
        
        public IActivityManagerHandler(Object base) {
            mBase = base;
        }
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 拦截startActivity方法
            if ("startActivity".equals(method.getName())) {
                // 修改参数,实现插件化等需求
                // ...
            }
            // 调用原始方法
            return method.invoke(mBase, args);
        }
    }
}

四、实践项目:实现一个简单的AOP框架

// 1. 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {
    String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Performance {
}

// 2. 创建切面处理器
public class AspectHandler implements InvocationHandler {
    private Object target;
    private Map<Method, List<MethodAdvice>> adviceMap = new HashMap<>();
    
    public AspectHandler(Object target) {
        this.target = target;
        scanAdvices();
    }
    
    private void scanAdvices() {
        Class<?> clazz = target.getClass();
        for (Method method : clazz.getDeclaredMethods()) {
            List<MethodAdvice> advices = new ArrayList<>();
            
            // 检查Log注解
            if (method.isAnnotationPresent(Log.class)) {
                advices.add(new LogAdvice());
            }
            
            // 检查Performance注解
            if (method.isAnnotationPresent(Performance.class)) {
                advices.add(new PerformanceAdvice());
            }
            
            if (!advices.isEmpty()) {
                method.setAccessible(true);
                adviceMap.put(method, advices);
            }
        }
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        List<MethodAdvice> advices = adviceMap.get(method);
        
        // 执行前置通知
        if (advices != null) {
            for (MethodAdvice advice : advices) {
                advice.before(target, method, args);
            }
        }
        
        Object result;
        try {
            // 执行目标方法
            result = method.invoke(target, args);
            
            // 执行后置通知
            if (advices != null) {
                for (MethodAdvice advice : advices) {
                    advice.afterReturning(target, method, args, result);
                }
            }
        } catch (Exception e) {
            // 执行异常通知
            if (advices != null) {
                for (MethodAdvice advice : advices) {
                    advice.afterThrowing(target, method, args, e);
                }
            }
            throw e;
        } finally {
            // 执行最终通知
            if (advices != null) {
                for (MethodAdvice advice : advices) {
                    advice.after(target, method, args);
                }
            }
        }
        
        return result;
    }
}

// 3. 通知接口
public interface MethodAdvice {
    void before(Object target, Method method, Object[] args);
    void afterReturning(Object target, Method method, Object[] args, Object result);
    void afterThrowing(Object target, Method method, Object[] args, Throwable t);
    void after(Object target, Method method, Object[] args);
}

// 4. 日志通知实现
public class LogAdvice implements MethodAdvice {
    @Override
    public void before(Object target, Method method, Object[] args) {
        Log annotation = method.getAnnotation(Log.class);
        String message = annotation.value().isEmpty() ? 
            method.getName() + "方法开始执行" : annotation.value();
        System.out.println("[LOG] " + message);
    }
    
    @Override
    public void afterReturning(Object target, Method method, Object[] args, Object result) {
        System.out.println("[LOG] " + method.getName() + "方法执行成功");
    }
    
    @Override
    public void afterThrowing(Object target, Method method, Object[] args, Throwable t) {
        System.out.println("[LOG] " + method.getName() + "方法执行失败: " + t.getMessage());
    }
    
    @Override
    public void after(Object target, Method method, Object[] args) {
        System.out.println("[LOG] " + method.getName() + "方法执行结束");
    }
}

// 5. 使用示例
public class UserService {
    @Log("用户登录")
    @Performance
    public boolean login(String username, String password) {
        // 登录逻辑
        return true;
    }
    
    @Log("获取用户信息")
    public User getUserInfo(int userId) {
        // 获取用户信息逻辑
        return new User();
    }
}

// 6. 测试
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserService();
        
        AspectHandler handler = new AspectHandler(userService);
        UserService proxy = (UserService) Proxy.newProxyInstance(
            userService.getClass().getClassLoader(),
            userService.getClass().getInterfaces(),
            handler
        );
        
        // 调用方法,自动应用切面
        proxy.login("admin", "123456");
        proxy.getUserInfo(1);
    }
}

五、常见面试题及答案

Q1:反射的性能问题如何优化?

答案:

  1. 缓存反射结果(Method、Field、Constructor)
  2. 使用setAccessible(true)避免安全检查
  3. 使用MethodHandle(Java 7+)
  4. 使用字节码生成库(如ASM、CGLIB)

Q2:动态代理和静态代理的区别?

答案:

特性静态代理动态代理
创建时机编译期运行期
代理类数量每个目标类需要一个代理类一个代理类处理多个接口
灵活性低,需要手动编写代理类高,可动态生成
维护成本
性能稍好稍差(首次创建代理类有开销)

Q3:动态代理在Android中的应用场景?

答案:

  1. Retrofit网络库:通过动态代理创建API接口实例
  2. ARouter路由框架:通过动态代理实现组件通信
  3. 插件化框架:Hook系统服务,实现插件加载
  4. AOP框架:实现日志、权限检查、性能监控等

六、学习建议

  1. 动手实践:按照上面的代码示例逐行敲一遍
  2. 源码阅读:阅读Java的Proxy类和InvocationHandler源码
  3. 性能测试:编写测试代码比较反射、动态代理和直接调用的性能差异
  4. 框架学习:学习Spring、Retrofit等框架中如何应用动态代理

学习路线建议:

反射基础 → 动态代理 → Android Framework中的应用 → 
AOP实现 → 性能优化 → 源码分析

记住,反射和动态代理是理解Android Framework很多机制的基础,尤其是在插件化、热修复、AOP等高级技术中。