代理模式 面向对象编程(OOP)可能是编程中最流行的概念。然而,Spring引入了另一种编码规范,面向切面编程(AOP)。为了简化定义,AOP是面向系统特定点的一种编程,如:异常抛出,特定类别方法的执
代理模式
面向对象编程(OOP)可能是编程中最流行的概念。然而,Spring引入了另一种编码规范,面向切面编程(AOP)。为了简化定义,AOP是面向系统特定点的一种编程,如:异常抛出,特定类别方法的执行等.AOP允许在执行这些特定点之前或之后执行补充动作。如何实现这种操作?它可以通过监听器(listeners)进行。但在这种情况下,我们应该在只要可能存在调用的地方都需要定义监听器来进行监听(比如在一个方法的开始的地方)。这就是为什么Spring不采用这个idea。相反,Spring实现了一种能够通过额外的方法调用完成任务的设计模式 - 代理设计模式。
代理就像对象的镜像一样。也正因为如此,代理对象不仅可以覆盖真实对象,还可以扩展其功能。因此,对于只能在屏幕上打印一些文本的对象,我们可以添加另一个对象来过滤显示单词。可以通过代理来定义第二个对象的调用。代理是封装真实对象的对象。例如,如果您尝试调用Waiter bean,那么您将调用该Bean的代理,其行为方式完全相同。
代理设计模式的一个很好的例子是org.springframework.aop.framework.ProxyFactoryBean。该工厂根据Spring bean构建AOP代理。该类实现了定义getObject()方法的 FactoryBean
接口。此方法用于将需求 Bean
的实例返回给 bean factory
。在这种情况下,它不是返回的实例,而是 AOP代理
。在执行代理对象的方法之前,可以通过调用补充方法来进一步“修饰”代理对象(其实所谓的静态代理不过是在装饰模式上加了个要不要你来干动作行为而已,而不是装饰模式什么也不做就加了件衣服,其他还得由你来全权完成)。
ProxyFactory
的一个例子是:
public class TestProxyAop { @Test public void test() { ProxyFactory factory = new ProxyFactory(new House()); factory.addInterface(Construction.class); factory.addAdvice(new BeforeConstructAdvice()); factory.setExposeProxy(true); Construction construction = (Construction) factory.getProxy(); construction.construct(); assertTrue("Construction is illegal. " + "Supervisor didn't give a permission to build " + "the house", construction.isPermitted()); }}interface Construction { public void construct(); public void givePermission(); public boolean isPermitted();}class House implements Construction{ private boolean permitted = false; @Override public boolean isPermitted() { return this.permitted; } @Override public void construct() { System.out.println("I'm constructing a house"); } @Override public void givePermission() { System.out.println("Permission is given to construct a simple house"); this.permitted = true; }}class BeforeConstructAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] arguments, Object target) throws Throwable { if (method.getName().equals("construct")) { ((Construction) target).givePermission(); } }}
这个测试应该通过,因为我们不直接在House实例上操作,而是代理它。代理调用第一个 BeforeConstructAdvice
的 before
方法(指向在执行目标方法之前执行,在我们的例子中为 construct()
)通过它,给出了一个“权限”来构造对象的字段(house)。代理层提供了一个额外新功能,因为它可以简单地分配给另一个对象。要做到这一点,我们只能在before方法之前修改过滤器。
复合模式
另一种结构模式是复合模式。在关于Spring中设计模式的第一篇文章中,我们使用构建器来构造复杂对象。另一种实现方法是使用复合模式。这种模式是基于具有共同行为的多个对象的存在,用于构建更大的对象。较大的对象仍然具有与最小对象相同的特征。那么用它来定义相同的行为。
复合对象的非Spring示例可以是一个写入HTML的文本对象,由包含span或em标签的段落组成:
-
public class CompositeTest { @Test public void test() { TextTagComposite composite = new PTag(); composite.addTag(new SpanTag()); composite.addTag(new EmTag()); // sample client code composite.startWrite(); for (TextTag leaf : composite.getTags()) { leaf.startWrite(); leaf.endWrite(); } composite.endWrite(); assertTrue("Composite should contain 2 tags but it contains "+composite.getTags().size(), composite.getTags().size() == 2); }}interface TextTag { public void startWrite(); public void endWrite();}interface TextTagComposite extends TextTag { public List<TextTag> getTags(); public void addTag(TextTag tag);}class PTag implements TextTagComposite { private List<TextTag> tags = new ArrayList<TextTag>(); @Override public void startWrite() { System.out.println("<p>"); } @Override public void endWrite() { System.out.println("</p>"); } @Override public List<TextTag> getTags() { return tags; } @Override public void addTag(TextTag tag) { tags.add(tag); }}class SpanTag implements TextTag { @Override public void startWrite() { System.out.println("<span>"); } @Override public void endWrite() { System.out.println("</span>"); }}class EmTag implements TextTag { @Override public void startWrite() { System.out.println("<em>"); } @Override public void endWrite() { System.out.println("</em>"); }}
在这种情况下,可以看到一个复合对象。我们可以区分复合与非复合对象,因为第一个可以容纳一个或多个非复合对象(
PTag
类中的privateListtags
字段)。非复合对象称为叶子。TextTag
接口被称为组件,因为它为两个对象类型提供了共同的行为规范(有点像Linux
文件管理系统的有共同点的文件放在一个文件夹下进行管理,其实就是节点管理)。
在 Spring
世界中,我们检索复合对象的概念是org.springframework.beans.BeanMetadataElement接口,用于配置 bean
对象。它是所有继承对象的基本界面。现在,在一方面,我们有一个叶子,由org.springframework.beans.factory.parsing.BeanComponentDefinition表示,另一边是复合org.springframework.beans.factory.parsing.CompositeComponentDefinition。 CompositeComponentDefinition
类似于组件,因为它包含addNestedComponent(ComponentDefinition component)方法,它允许将叶添加到私有final列表中 nestedComponents
。您可以看到,由于此列表, BeanComponentDefinition
和 CompositeComponentDefinition
的组件是org.springframework.beans.factory.parsing.ComponentDefinition。