揭秘Spring(四)_Spring设计模式

引:说完了IOC和AOP(虽然可能还是不够深入,不够全面,但是对于自己还是有一定的收获,日后有新的领悟再来调整),再来说说Spring这么优秀的框架所使用的的设计模式,可谓遍地都是,我就自己看到写一下。

单例模式

单例模式的的原理可以参照设计模式之禅——单例模式

Spring应用到的单例模式可以在org.springframework.beans.factory.config.AbstractFactoryBean类中看到这个逻辑。看看它的getObject方法:

1
2
3
4
public final T getObject() throws Exception {
// 如果是单例且已经初始化,就直接返回
return this.isSingleton()?(this.initialized?this.singletonInstance:this.getEarlySingletonInstance()):this.createInstance();
}

工厂方法模式

工厂方法模式的的原理可以参照设计模式之禅——工厂方法模式

Spring应用到的工厂方法模式可以在org.springframework.beans.factory.BeanFactory类中看到这个逻辑。我们看到下面的代码:

1
2
3
4
public interface BeanFactory {
// 根据唯一标识来获得Bean对象
Object getBean(String var1) throws BeansException;
}

抽象工厂模式

抽象工厂模式的的原理可以参照设计模式之禅——抽象工厂模式

Spring应用到的抽象工厂模式可以在org.springframework.beans.factory.BeanFactory类中看到这个逻辑。通过它的实现,我们可以从Spring的容器访问bean。根据采用的策略,getBean方法可以返回已创建的对象(共享实例,单例作用域)或初始化新的对象(原型作用域)。在BeanFactory的实现中,我们可以区分:ClassPathXmlApplicationContext,XmlWebApplicationContext,StaticWebApplicationContext,StaticPortletApplicationContext,GenericApplicationContext,StaticApplicationContext,相当于不同的Creator。

建造者模式

建造者模式的的原理可以参照设计模式之禅——建造者模式

Spring应用到的建造者模式可以在org.springframework.beans.factory.support.BeanDefinitionBuilder类中检索这个逻辑。这是一个允许我们以编程方式定义bean的类。BeanDefinitionBuilder包含几个方法,它们为AbstractBeanDefinition抽象类的相关实现设置值,比如作用域,工厂方法,属性等。想看看它是如何工作的,请查看以下这些方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class BeanDefinitionBuilder {

private AbstractBeanDefinition beanDefinition;

// 设置Bean的父类名
public BeanDefinitionBuilder setParentName(String parentName) {
this.beanDefinition.setParentName(parentName);
return this;
}

// 设置Bean的工厂方法
public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
this.beanDefinition.setFactoryMethodName(factoryMethod);
return this;
}

// 设置Bean的构造函数参数
public BeanDefinitionBuilder addConstructorArgValue(Object value) {
this.beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(
this.constructorArgIndex++, value);
return this;
}

// 添加Bean的属性值
public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
this.beanDefinition.getPropertyValues().add(name, value);
return this;
}

// 设置Bean的初始化方法
public BeanDefinitionBuilder setInitMethodName(String methodName) {
this.beanDefinition.setInitMethodName(methodName);
return this;
}

// 返回建造好的对象
public AbstractBeanDefinition getBeanDefinition() {
this.beanDefinition.validate();
return this.beanDefinition;
}
}

原型模式

原型模式的的原理可以参照设计模式之禅——原型模式

Spring应用到的原型模式可以在org.springframework.beans.factory.support.AbstractBeanFactory类中看到这个逻辑。它使用一种特定的原型设计模式,它先初始化bean原型作用域(克隆)。新对象基于配置文件中的bean定义。

模板模式

模板模式的的原理可以参照设计模式之禅——模板模式

Spring应用到的模板模式可以在org.springframework.context.support.AbstractApplicationContext类以及它的实现类中看到这个逻辑。它的模板方法是refresh方法,而refreshBeanFactory以及getBeanFactory等方法都由子类具体实现。

访问者模式

访问者模式模式的的原理可以参照设计模式之禅——访问者模式

Spring应用到的访问者模式可以在org.springframework.beans.factory.config.BeanDefinitionVisitor类中看到这个逻辑。该对象用于解析bean元数据并将其解析为String(例如:具有作用域或工厂方法名称的XML属性)或Object(例如:构造函数定义中的参数)。已解析的值在与分析的bean关联的BeanDefinition实例中进行判断设置。具体的源码请看BeanDefinitionVisitor的代码片段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class BeanDefinitionVisitor {

public void visitBeanDefinition(BeanDefinition beanDefinition) {
visitParentName(beanDefinition);
visitBeanClassName(beanDefinition);
visitFactoryBeanName(beanDefinition);
visitFactoryMethodName(beanDefinition);
visitScope(beanDefinition);
visitPropertyValues(beanDefinition.getPropertyValues());
ConstructorArgumentValues cas = beanDefinition.
getConstructorArgumentValues();
visitIndexedArgumentValues(cas.
getIndexedArgumentValues());
visitGenericArgumentValues(cas.
getGenericArgumentValues());
}

protected void visitParentName(BeanDefinition beanDefinition) {
String parentName = beanDefinition.getParentName();
if (parentName != null) {
String resolvedName = resolveStringValue(parentName);
if (!parentName.equals(resolvedName)) {
beanDefinition.setParentName(resolvedName);
}
}
}

}

代理模式

代理模式的的原理可以参照设计模式之禅——代理模式

Spring应用到的代理模式可以在org.springframework.aop.framework.ProxyFactoryBean类中看到这个逻辑。详细说明可以参照上一篇文章。

策略模式

策略模式的的原理可以参照设计模式之禅——策略模式

Spring应用到的策略模式可以在org.springframework.aop.framework.DefaultAopProxyFactory类中看到这个逻辑。看一下这个类的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if(!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
Class<?> targetClass = config.getTargetClass();
if(targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
} else {
// 根据目标类是否有接口而采取不同的策略
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass)?new ObjenesisCglibAopProxy(config):new JdkDynamicAopProxy(config));
}
}
}

}

适配器模式

适配器模式的的原理可以参照设计模式之禅——适配器模式

Spring应用到的适配器模式可以在org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry类中看到这个逻辑,Spring需要将每个Advice(通知)都封装成对应的拦截器类型,返回给容器,所以需要使用适配器模式对Advice进行转换。下面我们看看具体的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Adaptee
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, Object target) throws Throwable;
}

// Target
public interface AdvisorAdapter {
boolean supportsAdvice(Advice advice);

MethodInterceptor getInterceptor(Advisor advisor);
}

// Adapter
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}

public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}

}

观察者模式

观察者模式的的原理可以参照设计模式之禅——观察者模式

Spring应用到的观察者模式可以应用程序上下文相关的事件传输看到这个逻辑,具体一点在AbstractApplicationContext与org.springframework.context.ApplicationListener以及org.springframework.context.event.ApplicationEventMulticaster中看到,我们可以看到下面的相关代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean {
// 定义传播者,用来传播消息
private ApplicationEventMulticaster applicationEventMulticaster;
// 注册监听者
protected void registerListeners() {
...
}
}

public interface ApplicationEventMulticaster {
void addApplicationListener(ApplicationListener<?> var1);

void addApplicationListenerBean(String var1);

void removeApplicationListener(ApplicationListener<?> var1);

void removeApplicationListenerBean(String var1);

void removeAllListeners();

void multicastEvent(ApplicationEvent var1);

void multicastEvent(ApplicationEvent var1, ResolvableType var2);
}

解释器模式

解释器模式的的原理可以参照设计模式之禅——解释器模式

Spring应用到的解释器模式主要以Spring Expression Language(SpEL)为例。SpEL是一种由Spring的org.springframework.expression.ExpressionParser实现分析和执行的语言。这些实现使用作为字符串给出的Spel表达式,并将它们转换为org.springframework.expression.Expression的实例。上下文组件由org.springframework.expression.EvaluationContext实现表示,例如:StandardEvaluationContext。

参考

参考了超级多,都快忘了,各位大佬不要介意!