动态代理和静态代理

静态代理

流程图:

代理类:

被代理类: 

 main:

接口:

分析: 

动态代理

流程图:

代理类:

被代理类:

接口:

main:

 分析:

区别:


静态代理

流程图:

 

代理类:

package com.gao.demo02;

public class UserServiceProxy implements  UserService{
    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    public void add(){
        log("add");
        userService.add();
    }

    public void delete(){
        log("delete");
        userService.add();
    }

    public void update(){
        log("update");
        userService.add();
    }

    public void query(){
        log("query");
        userService.add();
    }

    public void log(String msg){
        System.out.println("[Debug]使用了"+msg+"方法");
    }
}

被代理类: 

package com.gao.demo02;

public class UserServiceImpl implements UserService{
    public void add(){
        System.out.println("增加了一个用户");
    }
    public void delete(){
        System.out.println("删除了一个用户");
    }
    public void update(){
        System.out.println("修改了一个用户");
    }
    public void query(){
        System.out.println("查询了一个用户");
    }
}

 main:

package com.gao.demo02;

public class Client {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        UserServiceProxy proxy = new UserServiceProxy();
        proxy.setUserService(userService);
        proxy.add();
    }
}

接口:

package com.gao.demo02;

public interface UserService {
     void add();
     void delete();
     void update();
     void query();
}

分析: 

静态代理类优缺点  
优点:

        业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。 

缺点: 
        1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。 
        2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

动态代理

流程图:

 

代理类:

package com.gao.demo04;

import com.gao.demo03.Rent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//这个可以做成一个公共类

//这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //生成代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{
        log(method.getName());
        //动态代理的本质就是使用反射机制实现(通过invoke方法,反射执行代理类)
        Object result =method.invoke(target,args);
        return result;
    }

    public void log(String msg){
        System.out.println("执行了"+msg+"方法");
    }
}

被代理类:

package com.gao.demo03;

public class Host implements Rent {
    public void rent(){
        System.out.println("房东要出租房子!");
    }
}

接口:

package com.gao.demo03;

public interface Rent {
    public void rent();
}

main:

package com.gao.demo04;

import com.gao.demo02.UserService;//使用了demo2的类
import com.gao.demo02.UserServiceImpl;

public class Client {
    public static void main(String[] args) {
        UserServiceImpl userService = new UserServiceImpl();
        //代理角色,不存在
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        pih.setTarget(userService);//设置要代理的对象
        //动态生成代理类
        UserService proxy = (UserService) pih.getProxy();
        proxy.delete();
    }
}

 分析:

        我们可以通过LogHandler代理不同类型的对象,如果我们把对外的接口都通过动态代理来实现,那么所有的函数调用最终都会经过invoke函数的转发,因此我们就可以在这里做一些自己想做的操作,比如日志系统、事务、拦截器、权限控制等。这也就是AOP(面向切面编程)的基本原理。

区别:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值