## Java专题九(2):动态代理
[TOC]
#### JDK静态代理
> 使用接口代理实现类的方法调用
定义一个接口
~~~
public interface HelloService {
void sayHello();
}
~~~
定义一个实现类
~~~
public class HelloServiceImpl implements HelloService{
@Override
public void sayHello() {
System.out.println("say hello...");
}
}
~~~
测试代理方法
~~~
public class HelloTest {
public static void main(String[] args){
HelloService hello = new HelloServiceImpl();
hello.sayHello();
}
}
~~~
输出
~~~
say hello...
~~~
#### JDK动态代理
- 可以隐藏委托类
- 在不修改委托类代码的情况下,可以为委托类的方法增加一些操作,如方法中实际代码前后增加日志输出
> 首先通过Proxy为委托类创建代理对象,将代理对象上对方法的调用通过`InvocationHandler`分发给实际的委托类调用,只能为实现了接口的类提供代理。
定义一个接口
~~~
public interface HelloService {
void sayHello();
}
~~~
定义一个委托类,实现接口
~~~
public class HelloServiceImpl implements HelloService{
@Override
public void sayHello() {
System.out.println("say hello...");
}
}
~~~
创建代理类,必须实现`InvocationHandler`接口
~~~
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
~~~
~~~
// java.lang.reflect.Proxy
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h){
// ...
}
~~~
~~~
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class HelloServiceProxy implements InvocationHandler {
private Object target;
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before invoked...");
Object result = method.invoke(target, args);
System.out.println("before invoked...");
return result;
}
}
~~~
测试代理方法
~~~
public class HelloTest {
public static void main(String[] args){
HelloServiceProxy helloServiceProxy = new HelloServiceProxy();
HelloService proxy =
(HelloService) helloServiceProxy.bind(new HelloServiceImpl());
proxy.sayHello();
}
}
~~~
输出
~~~
before invoked...
say hello...
before invoked...
~~~
#### CGLIB动态代理
HelloServer.java和HelloServiceImpl.java都不用改变,
~~~
public class HelloServiceCglib implements MethodInterceptor {
private Object target;
public Object getInstance(Object target){
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperClass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.setCallback(this);
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy porxy)
throws Throwable {
System.out.println("before invoked...");
Object returnObj = porxy.invokeSuper(obj, args);
System.out.println("before invoked...");
return returnObj ;
}
}
~~~
- JavaCook
- Java专题零:类的继承
- Java专题一:数据类型
- Java专题二:相等与比较
- Java专题三:集合
- Java专题四:异常
- Java专题五:遍历与迭代
- Java专题六:运算符
- Java专题七:正则表达式
- Java专题八:泛型
- Java专题九:反射
- Java专题九(1):反射
- Java专题九(2):动态代理
- Java专题十:日期与时间
- Java专题十一:IO与NIO
- Java专题十一(1):IO
- Java专题十一(2):NIO
- Java专题十二:网络
- Java专题十三:并发编程
- Java专题十三(1):线程与线程池
- Java专题十三(2):线程安全与同步
- Java专题十三(3):内存模型、volatile、ThreadLocal
- Java专题十四:JDBC
- Java专题十五:日志
- Java专题十六:定时任务
- Java专题十七:JavaMail
- Java专题十八:注解
- Java专题十九:浅拷贝与深拷贝
- Java专题二十:设计模式
- Java专题二十一:序列化与反序列化
- 附加专题一:MySQL
- MySQL专题零:简介
- MySQL专题一:安装与连接
- MySQL专题二:DDL与DML语法
- MySQL专题三:工作原理
- MySQL专题四:InnoDB存储引擎
- MySQL专题五:sql优化
- MySQL专题六:数据类型
- 附加专题二:Mybatis
- Mybatis专题零:简介
- Mybatis专题一:配置文件
- Mybatis专题二:映射文件
- Mybatis专题三:动态SQL
- Mybatis专题四:源码解析
- 附加专题三:Web编程
- Web专题零:HTTP协议
- Web专题一:Servlet
- Web专题二:Cookie与Session
- 附加专题四:Redis
- Redis专题一:数据类型
- Redis专题二:事务
- Redis专题三:key的过期
- Redis专题四:消息队列
- Redis专题五:持久化