Java中的反射机制和动态代理

反射机制

Java中的许多对象在运行时都会出现两种类型:编译时类型和运行时类型。如Person p = new Student();将会产生一个p变量,该变量的编译时类型为Person,运行时类型为Student。又如程序运行时接收到外部传入的一个对象,编译时类型为Object,运行时需要调用运行时的类型的方法。这种在编译时无法预知要使用哪个类型的情形,需要使用反射机制,即运行时获得类信息。
通常在开发通用性比较广的框架、基础平台时会大量使用反射,来动态创建某个类的对象。

Class类

类中之王Class是所有class的类,要在运行时获得类信息,即要在运行时获得Class类对象(见java.lang.Class类)。Class类没有public构造器,是通过JVM自动生成的,但是我们可以获得要通过反射操作的Class对象。

如何获得Class对象?

每个类被加载后会生成一个对应的Class对象存在JVM中。要获得改Class对象信息,有以下三种方式:
1)使用forName静态方法

Class<?> testClass = Class.forName("Test");

2)使用class属性

Class testClass = Test.class

3)使用getClass方法

如何操作Class对象?

1)通过Class对象的newInstance()方法创建类的实例。在许多框架中,需要根据配置文件来创建对象,即使用此方法。
2)或者先获取到Constructor对象,再调用Constructor的newInstance()方法创建实例。这种方法可以指定使用哪个构造器来创建对象实例。
参见java.lang.reflect包下的Method、Constructor、Field。
获得Method数组后,每个Method对象的invoke方法可以用来调用反射操作对象的相应方法。

使用反射生成动态代理

java.lang.reflect包下的Proxy类和InvocationHandler接口,用来生成动态代理。
Proxy提供了用于创建动态代理类和代理对象的静态方法,也是所有动态代理类的父类。
Proxy提供了以下两个方法来创建动态代理类和动态代理实例。

public static Class<?> getProxyClass(ClassLoader loader,
                                         Class<?>... interfaces)
        throws IllegalArgumentException
{
	final Class<?>[] intfs = interfaces.clone();
	final SecurityManager sm = System.getSecurityManager();
	if (sm != null) {
		checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
	}
	return getProxyClass0(loader, intfs);
}

创建一个动态代理类的Class对象。第一个ClassLoader参数指定了生成动态代理类的类加载器,动态代理类将实现第二个参数提供的所有接口。

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

直接创建一个动态代理实例,实现了所有接口,执行动态代理对象的每个方法都会被替换执行InvocationHandler对象的invoke方法。
Spring框架中的AOP,先实现InvocationHandler接口,重写invoke方法,将横切代码嵌入其中,实现面向切面编程。其中method.invoke()使用反射来调用被代理类。
使用时新建一个代理类,使用代理类来调用被代理类方法。

Spring AOP有哪些方式?

Java Proxy

动态构建代理对象

Cglib

动态构建代理对象

AspectJ

修改目标字节,编译时织入代理字节,基于eclipse

instrumentation

修改目标字节,在类装载时动态拦截并织入代理字节,javaagent

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值