这是我参与更文挑战的第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();
}
}
运行结果
在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 类
今日小结
今天看了看代理模式,从案例来说很简单,但是当它应用到Spring中的时候,初看很懵,不过先记住几个关键的东西,如代理模式->Spring AOP -> getObject() 以及JdkDynamicAopProxy 类和CglibAopProxy 类,全面的知识点在实战中再来一步一步往下走,好了,今日又Get了一个新的设计模式,再见。