动态代理
- 代理对象不需要实现接口,但是目标对象要实现接口,否则不能用动态代理
- 代理对象的生成,是利用JDK的API,动态代理在内存中构建代理对象
- 动态代理也叫做JDK代理、接口代理
1.接口
public interface ITeacherDao {
//授课方法
void teach();
void sayhello(String name);
}
2.目标对象(被代理对象)
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
System.out.println("老师正在授课...");
}
@Override
public void sayhello(String name) {
System.out.println("sayhello"+name);
}
}
3.代理工厂
public class ProxyFactory {
//维护一个目标对象
private Object target;
//构造器
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance(){
/*
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
ClassLoader loader:指定当前目标对象使用的类加载器,获取类加载器的方法固定
Class<?>[] interfaces:目标对象实现的接口类型,使用泛型方法确定类型
InvocationHandler h:事情处理,执行目标对象的方法时,会触发事情处理器方法,
会把当前执行的目标对象方法作为参数传入
*/
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK代理开始~~");
//反射机制调用目标对象的方法
return method.invoke(target,args);
}
});
}
}
4.客户端
public static void main(String[] args) {
//创建被代理对象
ITeacherDao target = new TeacherDao();
//给目标对象创建代理对象
ITeacherDao proxyInstance = (ITeacherDao) new ProxyFactory(target).getProxyInstance();
//proxyInstacne=class com.sun.proxy.$Proxy内存中动态生成了代理对象
System.out.println("proxyInstacne=" + proxyInstance.getClass());
//通过代理对象,调用目标对象的方法
//proxyInstance.teach();
proxyInstance.sayhello("圈圈");
}
输出:
JDK代理开始~~
sayhello 圈圈
动态代理的好处:(转自狂神说)
-
可以使真实角色的操作更加纯粹,不用去关注一些公共的业务!
-
公共业务交给代理角色完成,实现了业务的分工!
-
公共业务发生扩展的时候,方便集中管理!
-
一个动态代理类代理的是一个接口,一般对应一类业务!
-
一个动态代理类可以代理多个类,只要该类实现的是同一接口!