动态代理
最近在看aop,自然离不开动态代理,所以把动态代理的原理简单写一下。先来一个简单的例子。
public interface MethodInvocation {
void invoke();
}
public interface Advice extends InvocationHandler {
}
public interface HelloService {
void sayHelloWorld();
void sayHelloWorld2();
}``
public class HelloServiceImpl implements HelloService {
@Override
public void sayHelloWorld() {
System.out.println("hello world!");
}
@Override
public void sayHelloWorld2() {
System.out.println("hello world11!");
}
}
public class SimpleAOP {
public static Object getProxy(Object bean, Advice advice) {
return Proxy.newProxyInstance(SimpleAOP.class.getClassLoader(), bean.getClass().getInterfaces(), advice);
}
}
public class SimpleAOPTest {
@Test
public void getProxy() throws Exception {
// 1. 创建一个 MethodInvocation 实现类
MethodInvocation logTask = () -> System.out.println("log task start");
HelloServiceImpl helloServiceImpl = new HelloServiceImpl();
// 2. 创建一个 Advice
Advice beforeAdvice = new BeforeAdvice(helloServiceImpl);
// 3. 为目标对象生成代理
HelloService helloServiceImplProxy = (HelloService) SimpleAOP.getProxy(helloServiceImpl,beforeAdvice);
helloServiceImplProxy.sayHelloWorld();
helloServiceImplProxy.sayHelloWorld2();
}}
最重要的一段代码
Proxy.newProxyInstance(SimpleAOP.class.getClassLoader(), bean.getClass().getInterfaces(), advice)
最终是生成了一个代理类,继承了它继承自Proxy并实现了我们定义的HelloService接口,我们调用sayHelloWorld()。最终调用的其实是
结论:
因为JDK生成的最终真正的代理类,它继承自Proxy并实现了我们定义的HelloService接口,在实现HelloService接口方法的内部,通过反射调用了
InvocationHandlerImpl的invoke方法。
通过分析代码可以看出Java 动态代理,具体有如下四步骤:
1通过实现 InvocationHandler 接口创建自己的调用处理器;
2通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
3通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
4通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。