阅读 50

初识Spring Cloud系列——Spring Boot篇08|Java 开发实战

这是我参与更文挑战的第8天,活动详情查看: 更文挑战

本文正在参加「Java主题月 - Java 开发实战」,详情查看 活动链接

更文挑战已经持续到了第八天,今天感觉有点累,不过还是继续来把今天的学习任务搞定吧,今天来说说代理模式

代理模式 Proxy Pattern

意图:为其他对象提供一种代理以控制对这个对象的访问。

如何理解代理模式呢?

通俗的说,代理模式就类似我们现实中的中介,比如我们找工作,有一些工作介绍所能够帮我们找到合适的岗位;比如我们要租房子,但是我们不知道哪里有让我们满意的房源,那么这时找租房中介,他们就会提供手头很多房源供我们选择; 从租房的例子来看,中介方便了我们找到房源,对于房东来说,房东不希望把他的房源信息通过贴广的方式,会导致很多人找他,并且有时候找他还不是为了租房,他只想把信息暴露给有意租房的人,那么通过租房中介的代理,就能比较精准的把房源信息投放给指定人群,房东也不会被经常打扰

实现方式

public class ProxyPatternDemo {
    public static void main(String[] args) {
        Tenement tenement = new ProxyTenement("中关村一号房");

        //第一次需要从房东获取房源信息
        tenement.display();
        System.out.println("");
        // 房源信息不需要通过房东获取
        tenement.display();

    }
}
//创建一个房源接口
interface Tenement {
    void display();
}
//创建
class RealTenement implements Tenement {

    private String tenementName;

    public RealTenement(String tenementName){
        this.tenementName = tenementName;
        loadFromDisk(tenementName);
    }

    @Override
    public void display() {
        System.out.println("展示房源信息: " + tenementName);
    }

    private void loadFromDisk(String tenementName){
        System.out.println("从房东获取房源信息: " + tenementName);
    }
}

class ProxyTenement implements Tenement{

    private RealTenement realTenement;
    private String tenementName;

    public ProxyTenement(String tenementName){
        this.tenementName = tenementName;
    }

    @Override
    public void display() {
        //判断中介是否已经掌握了房源信息,有则不需要再找房东,没有则需要找房东拿
        if(realTenement == null){
            realTenement = new RealTenement(tenementName);
        }
        realTenement.display();
    }
}
复制代码

运行结果

image.png

在Spring中的应用

代理模式在Spring中主要体现在Spring框架的核心功能之一的AOP,通过AOP将切面通知织入到指定的切点位置,简单一点就是可以是现在某个方法运行前后添加指定的功能。下面简单实现一个将拦截器织入指定的方法上。 在使用 Spring AOP 时,需要先配置好 ProxyFactoryBean,然后通过 ac.getBean(bean id) 来获取 ProxyFactoryBean 代理的对象。而 ProxyFactoryBean 类使用 ProxyFactoryBean.getObject() 方法获取返回的对象,即代理对象

以下是ProxyFactoryBean类核心方法getObject()的实现内容

    @Nullable
    public Object getObject() throws BeansException {
        this.initializeAdvisorChain();
        if (this.isSingleton()) {
            return this.getSingletonInstance();
        } else {
            if (this.targetName == null) {
                this.logger.info("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
            }

            return this.newPrototypeInstance();
        }
    }
复制代码

在getObject()方法中,主要调用getSingletonInstance()和newPrototypeInstance();

在Spring 的配置中,如果不做任何设置,那么Spring 代理生成的Bean 都是单例对象。 如果修改scope 则每次创建一个新的原型对象。

Spring 利用动态代理实现AOP 有两个非常重要的类,一个是JdkDynamicAopProxy 类和CglibAopProxy 类

image.png

今日小结

今天看了看代理模式,从案例来说很简单,但是当它应用到Spring中的时候,初看很懵,不过先记住几个关键的东西,如代理模式->Spring AOP -> getObject() 以及JdkDynamicAopProxy 类和CglibAopProxy 类,全面的知识点在实战中再来一步一步往下走,好了,今日又Get了一个新的设计模式,再见。

文章分类
后端
文章标签