spring中最重要的两个特性,1)IOC 2)AOP,而AOP最核心的技术就是java动态代理。
动态代理原理:JVM在内存中生成字节码文件(如下图),然后通过类加载器加载这个class文件在JVM方法区生成Class对象。其中类加载器加载class文件有两种方式。1)new 对象的时候隐式方式加载 2)通过Class.forName方式。
通过持久化动态代理类发现,生成的动态代理类有三个特性:1)是Proxy类的子类。2)实现被代理类的接口。3)被代理的方法通过扩展类的反射调用来实现。
接口:
package proxy;
public interface People {
public void study();
}
被代理的类:
package proxy;
public class Farmer implements People {
@Override
public void study() {
System.out.println("学习");
}
}
业务增强类:
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 这个类的作用是功能扩展
* @author lenovo
*
*/
public class InvocationHandlerImpl implements InvocationHandler {
private Object actor;//被代理的类为Object
public InvocationHandlerImpl(Object actor) {
super();
this.actor = actor;
}
@Override
public Object invoke(Object proxy, Method method, Object[] arg) throws Throwable {
doSomethingBefore();
Object obj = method.invoke(actor, arg);
doSomethingAfter();
return obj;
}
//执行前功能扩展
private void doSomethingBefore(){
System.out.println("doSomething before..");
}
//执行后功能扩展
private void doSomethingAfter(){
System.out.println("doSomething after..");
}
}
测试动态代理:
package proxy;
import java.lang.reflect.Proxy;
public class DynamicProxy {
public static void main(String[] args) {
People farmer = new Farmer();
InvocationHandlerImpl h = new InvocationHandlerImpl(farmer);
//获取动态代理类实例,底层是通过h.invoke来实现被代理方法执行和扩展的
People dynamicProxy = (People)Proxy.newProxyInstance(farmer.getClass().getClassLoader(), farmer.getClass().getInterfaces(), h);
dynamicProxy.study();
}
}
运行结果:
doSomething before..学习
doSomething after..
总结:
动态代理优点:
1)客户端和被代理对象之间的桥梁。
2)无侵入增强业务代码,解耦利器。
3)增强点多样化(业务前、后、异常)。
4)扩展能力强5)代码易维护
动态代理局限性:
1、被代理的类必须实现某一接口,如例子中的People。
2、动态代理基于反射运行期性能相对较差。