0
点赞
收藏
分享

微信扫一扫

【Spring第八篇】代理模式(静态、动态):Proxy_Mode

40dba2f2a596 2022-04-14 阅读 85
Spring框架

在了解aop之前我们先来了解代理模式


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KWD7o2sL-1649854268145)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20220310160338177.png)]

静态代理模式示例一

租房接口类 Rent

public interface Rent {
    public void rent();
}

房东类 Host

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

中介类 代理 Proxy 可以附带自己的一些属性

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Proxy implements Rent{

    private Host host;

    @Override
    public void rent() {
        host.rent();
        seeHouse();
        fare();
    }

    public void seeHouse(){
        System.out.println("中介带你看房");
    }

    public void fare(){
        System.out.println("收中介费");
    }
}

租客类 Client

public class Client {
    public static void main(String[] args) {
        
        Host host = new Host();
        Proxy proxy = new Proxy(host);

        //代理,中介帮房东租房子, 代理角色一般会有一些附属操作
        proxy.rent();
    }

}

静态代理模式示例二

service接口类 UserService

public interface UserService {

    public void add();
    public void delete();
    public void update();
    public void query();

}

service接口实现类

public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
        System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
        System.out.println("修改了一个用户");
    }

    @Override
    public void query() {
        System.out.println("查询了一个用户");
    }
}

代理 service实现类 UserServiceProxy

public class UserServiceProxy implements UserService{


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

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

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

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

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

    //打印日志方法
    public void log(String msg){
        System.out.println("使用了"+msg+"方法");
    }

}

用户执行

public class Client {

    public static void main(String[] args) {

        UserServiceImpl userService = new UserServiceImpl();

        UserServiceProxy proxy = new UserServiceProxy();
        proxy.setUserService(userService);

        proxy.add();
        System.out.println("==========");
        proxy.delete();
        System.out.println("==========");
        proxy.update();
        System.out.println("==========");
        proxy.query();
    }

}

总结:当我们的用户想要去调用service实现类的方法的时候,这时并不直接从service实现类中取得某个方法,而是通过接口去取

注意点:需要在代理实现类 UserServiceProxy 中编写以下代码

private UserServiceImpl userService;

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

当我们的用户 Client 在调用的使用只需编写以下代码

UserServiceImpl userService = new UserServiceImpl();

UserServiceProxy proxy = new UserServiceProxy();

proxy.setUserService(userService);

		proxy.add();
        System.out.println("==========");
        proxy.delete();
        System.out.println("==========");
        proxy.update();
        System.out.println("==========");
        proxy.query();

动态代理模式实例三

租房 接口 Rent

public interface Rent {


    public void rent();

}

房东 Host 实现接口

public class Host implements Rent {

    @Override
    public void rent() {
        System.out.println("房东出租房子");
    }
}

代理类 Proxy_InvocationHandler 实现 InvocationHandler接口

InvocationHandler

public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;
package com.kk.Demo03;

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

public class Proxy_InvocationHandler implements InvocationHandler {


    //被代理的接口
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }


    /**
     *  public static Object newProxyInstance(ClassLoader loader,
     *                                           Class<?>[] interfaces,
     *                                           InvocationHandler h)
     * 
     */
    //生成得到代理类
    public Object getProxy(){
     return  Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this );
    }


    //处理代理实例并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        seeHouse();
        fare();

        /**
         * public Object invoke(Object obj, Object... args)
         */
        //动态代理的本质就是实现反射机制
        Object result = method.invoke(rent, args);
        return result;
    }


    public void seeHouse(){
        System.out.println("中介带你看房");
    }

    public void fare(){
        System.out.println("收中介费");
    }
}

用户

public class Client {
    public static void main(String[] args) {
        //真实角色
        Host host = new Host();

        //代理角色
        Proxy_InvocationHandler handler = new Proxy_InvocationHandler();

        //通过调用 程序 处理  角色 来处理 要调用 的接口对象
        handler.setRent(host);

        Rent proxy = (Rent) handler.getProxy();//这里的proxy就是动态生成的,我们并没有写

        proxy.rent();
    }

}

动态代理模式实例四

Proxy_InvocationHandler

package com.kk.Demo04;

import com.kk.Demo03.Rent;

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

@SuppressWarnings("all")
public class Proxy_InvocationHandler 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 );
    }


    //处理代理实例并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        log(method.getName());

        //动态代理的本质就是实现反射机制
        Object result = method.invoke(target, args);
        return result;
    }



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


}

Client

package com.kk.Demo04;

import com.kk.Demo02.UserService;
import com.kk.Demo02.UserServiceImpl;

public class Client {
    public static void main(String[] args) {

        //真实角色
        UserServiceImpl userService = new UserServiceImpl();

        //代理角色,不存在
        Proxy_InvocationHandler handler = new Proxy_InvocationHandler();

        //设置要代理的对象
        handler.setTarget(userService);

        //动态生成代理类
        UserService proxy = (UserService) handler.getProxy();

        proxy.add();


    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xSLrLC4s-1649854268149)(C:\Users\30666\AppData\Roaming\Typora\typora-user-images\image-20220310170201823.png)]


举报

相关推荐

0 条评论