为什么要学习代理模式?这是springaop的底层【springaop和springmvc】
代理模式的分类:
静态代理
动态代理
静态代理中,我们对目标对象的每个方法的增强都是手动完成的(后面会具体演示代码_),非常不灵活(比如接口一旦新增加方法,目标对象和代理对象都要进行修改)且麻烦(_需要对每个目标类都单独写一个代理类)。 实际应用场景非常非常少,日常开发几乎看不到使用静态代理的场景。
立即学习“Java免费学习笔记(深入)”;
角色分析:
抽象角色:一般会使用接口或者抽象类来解决
真实角色:被代理的角色
代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
客户:访问代理对象的人!
代码步骤:
1、接口
public interface Rent {
public void rent();
}2、真实角色
//房东
public class Host implements Rent {
public void rent() {
System.out.println("房东要租房子");
}
}3、代理角色
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void rent(){
seeHouse();
host.rent();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房");
}
//收中介费
public void fare(){
System.out.println("中介收费");
}
}4、客服端访问代理角色
public class Client {
public static void main(String[] args) {
Host host = new Host();
//代理,代理角色一般会有附属操作!
Proxy proxy = new Proxy(host);
proxy.rent();
}
}代理模式的好处:
可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
公共也就交给代理角色!实现业务的分工!
公共业务发生扩展的时候,方便集中管理!
缺点:
一个真实角色会产生一个代理角色;从JVM角度来看,静态代理在编译时就将接口、实现类、代理类这些都变成了一个个实际的class文件。
AOP,的底层代理模式

动态代理和静态代理角色一样
动态代理的代理类是动态生成的,不是我们直接写好的!
功能列表:底层程序与前台页面分离的效果,对页面的修改无需改动任何程序代码。完善的标签系统,支持自定义标签,公用标签,快捷标签,动态标签,静态标签等等,支持标签内的vbs语法,原则上运用这些标签可以制作出任何想要的页面效果。兼容原来的栏目系统,可以很方便的插入一个栏目或者一个栏目组到页面的任何位置。底层模版解析程序具有非常高的效率,稳定性和容错性,即使模版中有错误的标签也不会影响页面的显示。所有的标
0
动态代理分为两大类:基于接口的动态代理,基于类的动态代理
基于接口——JDK动态代理
基于类:cglib动态代理
java字节码实现:javasist
需要了解两个类:Proxy: 代理类,InvocationHandler : 调用处理程序
从 JVM 角度来说,动态代理是在运行时动态生成类字节码,并加载到 JVM 中的。
//Proxy是生成动态代理类,提供了创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。 //InvocationHandler-- invoke 调用处理程序并返回接口, 是由代理实例的调用处理程序实现的接口 。
动态代理的好处:
可以使真实角色的操作更加纯粹!不用去关系一些公共的业务
公共也就交给代理角色!实现
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h){
}1.loader :类加载器,用于加载代理对象。
2.interfaces : 被代理类实现的一些接口;
3.h : 实现了 InvocationHandler 接口的对象;
要实现动态代理的话,还必须需要实现InvocationHandler 来自定义处理逻辑。 当我们的动态代理对象调用一个方法时,这个方法的调用就会被转发到实现InvocationHandler 接口类的 invoke 方法来调用。
public interface InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}1.proxy :动态生成的代理类
2.method : 与代理类对象调用的方法相对应
3.args : 当前 method 方法的参数
1、定义接口
public interface Rent {
public void rent();
}2、实现租房的接口
public class Host implements Rent {
@Override
public void rent() {
System.out.println("房东要租房");
}
}3、定义一个JDK动态代理类
public class DebugInvocationHandler implements InvocationHandler {
/**
* 代理类中的真实对象
*/
private final Object target;
public DebugInvocationHandler(Object target){
this.target = target;
}
/**
* 当你使用代理对象调用方法的时候实际会调用到这个方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//调用方法前
System.out.println("before method" + method.getName());
Object res = method.invoke(target, args);
//调用方法后
System.out.println("after method" + method.getName());
return res;
}
}invoke() 方法: 当我们的动态代理对象调用原生方法的时候,最终实际上调用到的是 invoke() 方法,然后 invoke() 方法代替我们去调用了被代理对象的原生方法。
4、获取代理对象的工厂类
public class JdkProxyFactory {
public static Object getProxy(Object target){
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new DebugInvocationHandler(target)
);
}
}getProxy() :主要通过Proxy.newProxyInstance()方法获取某个类的代理对象
5、实际使用
public static void main(String[] args) {
//Rent rent = new Host();
//Rent rentProxy= (Rent) Proxy.newProxyInstance(rent.getClass().getClassLoader(), rent.getClass().getInterfaces(),new DebugInvocationHandler(rent));
Rent rentProxy = (Rent)JdkProxyFactory.getProxy(new Host());
rentProxy.rent();
}运行上述代理的输出
before methodrent房东要租房after methodrent
以上就是Java中动态代理和静态代理的示例分析的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号