1. 程式人生 > 其它 >2022-2023年英語週報九年級第39期答案彙總

2022-2023年英語週報九年級第39期答案彙總

代理模式

使用一個代理物件將物件包裝起來,然後用該代理物件來取代該物件,任何對原始物件的呼叫都要通過代理,代理物件決定是否以及何時呼叫原始物件的方法 .

來源於這篇部落格

以下例子來源於大神狂神!!!

1、靜態代理

1. Rent介面,負責出租房子的人和中介共同需要乾的事出租房子

//租房
public interface Rent {

    //租房子
    public void rent();

}

2. Proxy表示中介去繼承租房的介面

  • 房東只需要把房子交給中介就行了,有中介代理,中介有些自己的事情要做....
@Component(value = "proxy")
public class Proxy implements Rent{
    @Autowired
    @Qualifier("host")
    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    @Override
    public void rent() {
        lookHouse();
        host.rent();
        signContract();
        harvestFees();
    }

    public void lookHouse(){
        System.out.println("看"  + host.getHostName() +"的房子");
    }

    public void signContract(){
        System.out.println("籤合同");
    }

    public void harvestFees(){
        System.out.println("收中介費");
    }

}

3. 房東Host,需要出租房屋,他就只幹一件事,租房子

@Component(value = "host")
public class Host implements Rent{

    private String hostName;

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

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

4. 需要租房的人,People,需要找中介租房,不直接聯絡房東,由中介全權代理

//需要租房的人
public class People {

    @Test
    public void makeHouse(){

        ApplicationContext context = new AnnotationConfigApplicationContext(SsyConfig.class);

        Host host = context.getBean("host", Host.class);
        host.setHostName("水三丫");
        Proxy proxy = context.getBean("proxy", Proxy.class);
        proxy.rent();

    }
}

//執行結果
看水三丫的房子
房東要出租房
籤合同
收中介費

Process finished with exit code 0

靜態代理的缺點:一個真實的角色會引數一個代理角色,程式碼量會翻倍,需要動態代理來解決

2、動態代理

利用Java的反射技術(Java Reflection),在執行時建立一個實現某些給定介面的新類(也稱“動態代理類”)及其例項(物件),代理的是介面(Interfaces),不是類(Class),也不是抽象類。在執行時才知道具體的實現,spring aop就是此原理。

參考一笑而過者也部落格

2.1 需要了解兩個類

  • Proxy:代理
    @CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
  1. loader: 用哪個類載入器去載入代理物件

  2. interfaces:動態代理類需要實現的介面

  3. h:動態代理方法在執行時,會呼叫h裡面的invoke方法去執行

  • InvocationHandler介面:呼叫處理程式

2.2 測試

  • 需要代理的介面
public interface UserService {

    public void add();

    public void update();

    public void delete();

    public void query();
}
  • 實現該介面的類
public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加了一個使用者");
    }

    @Override
    public void update() {
        System.out.println("更新了一個使用者");
    }

    @Override
    public void delete() {
        System.out.println("刪除了一個使用者");
    }

    @Override
    public void query() {
        System.out.println("查詢了一個使用者");
    }
}
  • 實現該InvocationHandler介面的通過反射獲取代理類的類
@Component("proxyInvocationHandler")
public class ProxyInvocationHandler implements InvocationHandler {

    private Object target;

    public Object getTarget() {
        return target;
    }

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

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


    //處理代理事例並返回結果,當代理類呼叫方法時會走這個method,invoke()
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println(method.getName());
        before();
        Object result = method.invoke(target, args);
        after();
        return result;
    }

    public void before(){
        System.out.println("操作之前列印日誌");
    }


    public void after(){
        System.out.println("操作之後列印日誌");
    }
}
  • 需要操作的客戶
public class UserServlet {

    @Test
    public void test(){
        ApplicationContext context = new AnnotationConfigApplicationContext(SsyConfigService.class);

        UserServiceImpl userServiceImpl = context.getBean("userService", UserServiceImpl.class);
        ProxyInvocationHandler pih = context.getBean("proxyInvocationHandler", ProxyInvocationHandler.class);

        pih.setTarget(userServiceImpl);


        UserService proxy = (UserService) pih.getProxy();

        proxy.update();
    }

}