前言:动态代理可以帮助我们使用代理类完成我们自身所不能操作不及的事情,aop的实现也可以由此实现。本文章,仅仅单独片面的讲了两者的简单的使用,以及使用上的区别。对于他们的实现方式,没有做出分析,在此先告知读者。
学习本章你可以获得什么:
1、通过 JDK 的 proxy 实现代理。
2、通过Cglib的方式实现代理。
3、明白两者的一个区别。
Proxy的用法
前提:目标类必须实现 接口
案例:
接口类:
public interface HelloWorld {
String sayHello(String str);
}
带强化的目标类:
public class HelloWorldImp implements HelloWorld {
@Override
public String sayHello(String str) {
return "HelloWorld: " + str;
}
}
动态实现类:
public class LogInvocationHandler implements InvocationHandler {
private HelloWorld helloWorld;
public LogInvocationHandler(HelloWorld helloWorld){
this.helloWorld = helloWorld;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("sayHello".equals(method.getName())) {
System.out.println("You said:"+Arrays.toString(args));
}
return method.invoke(helloWorld, args);
}
}
静态实现类:
public class StaticProxiedHelloWorld implements HelloWorld {
HelloWorld helloWorldImp = new HelloWorldImp();
@Override
public String sayHello(String str) {
return helloWorldImp.sayHello(str);
}
}
使用类:
public class Test {
public static void main(String[] args) {
HelloWorld hello = (HelloWorld) Proxy.newProxyInstance(
Test.class.getClassLoader(), // 1. 类加载器
new Class<?>[]{HelloWorld.class}, // 2. 代理需要实现的接口,可以有多个
new LogInvocationHandler(new HelloWorldImp()));// 3. 方法调用的实际处理者
System.out.println(hello.sayHello("I love you!"));
}
}
Cglib 的用法
前言:这里与上面proxy的区别是,这里我们的代理目标类可以不用必须实现接口。
案例:
目标类:
public class HelloWorld {
public void Said(){
System.out.println("Are You OK");
}
}
增强目标的代理类:
public class HelloWorldProxy implements MethodInterceptor {
private Object helloWorld;
public Object getInstance(Object object) {
this.helloWorld = object;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.helloWorld.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Lcj,said:");
method.invoke(helloWorld, objects);
System.out.println("Ljt ok");
return null;
}
}
测试类:
public class Test {
public static void main(String[] args) {
HelloWorldProxy helloWorldProxy = new HelloWorldProxy();
HelloWorld helloWorld = (HelloWorld)helloWorldProxy.getInstance(new HelloWorld());
helloWorld.Said();
}
}
两者的区别是通过 JDK方式的代理,目标类必须实现接口,而通过Cglib的方式,目标类可不比必须实现接口。