Struts2框架及其设计模式

Struts2容器

         容器是框架的核心,可以利用容器生成bean,也可以完成依赖注入等,这些都是容器的基本功能,Struts2容器与之前介绍的Spring容器、Springmvc容器是大不一样的。Spring典型容器是ClassPathXmlApplicationContext,Springmvc延续Spring的风格,其典型容器是XmlWebApplicationContext,它们都是AbstractRefreshableApplicationContext的子类,以下为AbstractRefreshableApplicationContext、DefaultListableBeanFactory部分源码:

// AbstractRefreshableApplicationContext.java部分源码
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {

	private Boolean allowBeanDefinitionOverriding;

	private Boolean allowCircularReferences;

	// 包含DefaultListableBeanFactory
	private DefaultListableBeanFactory beanFactory;

	/** Synchronization monitor for the internal BeanFactory */
	private final Object beanFactoryMonitor = new Object();
	
// 	DefaultListableBeanFactory部分源码
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

	/** Map from serialized id to factory instance */
	private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
			new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);

	/** Optional id for this factory, for serialization purposes */
	private String serializationId;

	/** Whether to allow re-registration of a different definition with the same name */
	private boolean allowBeanDefinitionOverriding = true;

	/** Whether to allow eager class loading even for lazy-init beans */
	private boolean allowEagerClassLoading = true;

	/** Resolver to use for checking if a bean definition is an autowire candidate */
	private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();

	/** Map from dependency type to corresponding autowired value */
	private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);

	/** Map of bean definition objects, keyed by bean name */
	// BeanDefinition键值对
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

	/** Map of singleton and non-singleton bean names keyed by dependency type */
	private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);

	/** Map of singleton-only bean names keyed by dependency type */
	private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);

	/** List of bean definition names, in registration order */
	private final List<String> beanDefinitionNames = new ArrayList<String>();

	/** Whether bean definition metadata may be cached for all beans */
	private boolean configurationFrozen = false;

	/** Cached array of bean definition names in case of frozen configuration */
	private String[] frozenBeanDefinitionNames;

在Spring中,以Map<String, BeanDefinition> beanDefinitionMap形式缓存xml等配置解析后的BeanDefinition,且DefaultListableBeanFactory(AbstractBeanFactory)提供多种形式的getBean,以获取bean。

        在Struts2中,其容器为ContainerImpl:

// ContainerImpl.java部分源码
class ContainerImpl implements Container {

	// 其体现在InternalFactory的键值对,缓存的都是InternalFactory
	// 直接利用InternalFactory创建bean
	final Map<Key<?>, InternalFactory<?>> factories;
	final Map<Class<?>, Set<String>> factoryNamesByType;

	
// InternalFactory.java
interface InternalFactory<T> extends Serializable {

	/**
	* Creates an object to be injected.
	*
	* @param context of this injection
	* @return instance to be injected
	*/
	T create(InternalContext context);
}

Struts2框架中的设计模式

ThreadLocal设计模式

       ContainerHolder的ThreadLocal设计模式实现:

/** ContainerHolder.java */
// ContainerHolder为典型的ThreadLocal设计模式实现
class ContainerHolder {

    private static ThreadLocal<Container> instance = new ThreadLocal<Container>();

    public static void store(Container instance) {
        ContainerHolder.instance.set(instance);
    }

    public static Container get() {
        return ContainerHolder.instance.get();
    }

    public static void clear() {
        ContainerHolder.instance.remove();
    }

}

         ThreadLocal设计模式本质:

/** ThreadLocal.java */
public void set(T value) {
	// 获取当前线程
	Thread t = Thread.currentThread();
	// 获取当前线程的threadLocals属性
	ThreadLocalMap map = getMap(t);
	if (map != null)
		// 设置ThreadLocal—instance键值对
		map.set(this, value);
	else
		// 创建ThreadLocalMap,且设置ThreadLocal对应的初始值
		createMap(t, value);
}

ThreadLocalMap getMap(Thread t) {
	return t.threadLocals;
}

/** Thread.java */
// Thread部分源码
public class Thread implements Runnable {
	/* ThreadLocal values pertaining to this thread. This map is maintained
	 * by the ThreadLocal class. */
	ThreadLocal.ThreadLocalMap threadLocals = null;
	...
}

/** ThreadLocalMap.java */
private void set(ThreadLocal key, Object value) {

		// We don't use a fast path as with get() because it is at
		// least as common to use set() to create new entries as
		// it is to replace existing ones, in which case, a fast
		// path would fail more often than not.

		Entry[] tab = table;
		int len = tab.length;
		int i = key.threadLocalHashCode & (len-1);

		for (Entry e = tab[i];
			 e != null;
			 e = tab[i = nextIndex(i, len)]) {
			ThreadLocal k = e.get();

			if (k == key) {
				e.value = value;
				return;
			}

			if (k == null) {
				replaceStaleEntry(key, value, i);
				return;
			}
		}

		tab[i] = new Entry(key, value);
		int sz = ++size;
		if (!cleanSomeSlots(i, sz) && sz >= threshold)
			rehash();
	}
	
/** ThreadLocal.java */
void createMap(Thread t, T firstValue) {
	t.threadLocals = new ThreadLocalMap(this, firstValue);
}

         ThreadLocal设计模式针对thread是线程安全的,在Thread中有ThreadLocal.ThreadLocalMap threadLocals属性,其key-value对应为ThreadLocal—实际存储对象,所以在多线程并发情况下,每一个线程存储的是对象的副本,线程之间隔离,这样当前线程对副本的操作不存在竞争关系,从这个层面体现为线程安全的。ThreadLocal设计模式在Struts2体现的淋漓尽致。

内部类工厂设计模式

        以ContainerBuilder中添加InternalFactory为例说明:

/** ContainerBuilder.java */
public <T> ContainerBuilder factory(Class<T> type,
  Class<? extends T> implementation, Scope scope) {
	return factory(type, Container.DEFAULT_NAME, implementation, scope);
}

public <T> ContainerBuilder factory(final Class<T> type, final String name,
  final Class<? extends T> implementation, final Scope scope) {
	// This factory creates new instances of the given implementation.
	// We have to lazy load the constructor because the Container
	// hasn't been created yet.
	InternalFactory<? extends T> factory = new InternalFactory<T>() {

	  volatile ContainerImpl.ConstructorInjector<? extends T> constructor;

	  @SuppressWarnings("unchecked")
	  public T create(InternalContext context) {
		if (constructor == null) {
		  this.constructor =
			  context.getContainerImpl().getConstructor(implementation);
		}
		return (T) constructor.construct(context, type);
	  }

	  @Override
	  public String toString() {
		return new LinkedHashMap<String, Object>() {{
		  put("type", type);
		  put("name", name);
		  put("implementation", implementation);
		  put("scope", scope);
		}}.toString();
	  }
	};

	return factory(Key.newInstance(type, name), factory, scope);
}

private <T> ContainerBuilder factory(final Key<T> key,
  InternalFactory<? extends T> factory, Scope scope) {
	ensureNotCreated();
	checkKey(key);
	final InternalFactory<? extends T> scopedFactory =
		scope.scopeFactory(key.getType(), key.getName(), factory);
	factories.put(key, scopedFactory);
	if (scope == Scope.SINGLETON) {
	  singletonFactories.add(new InternalFactory<T>() {
		public T create(InternalContext context) {
		  try {
			context.setExternalContext(ExternalContext.newInstance(
				null, key, context.getContainerImpl()));
			return scopedFactory.create(context);
		  } finally {
			context.setExternalContext(null);
		  }
		}
	  });
	}
	return this;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼CSDN产品总监范凯(网名:robbin)以及51CTO等技术社区鼎力推荐。   本书以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2的技术内幕提供了大量真知灼见。同样重要的是,本书还深入挖掘并分析了Struts2源代码实现中蕴含的大量值得称道的编程技巧和设计模式,这对开发者从Struts2的设计原理上去掌握和悟透Web层开发的要点和本质提供了绝佳的指导。   本书主要分为3大部分,内容安排具有极强的逻辑推理性,章和章之间互相呼应且互为印证。知识准备篇首先介绍了获取、阅读和调试Struts2源代码的方法,以及Struts2源代码的组织形式;然后厘清了Web开发中极易混淆的一些重要概念,以及Struts2的核心技术、宏观视图、微观元素、配置元素等,提纲挈领地对Struts2进行了多角度的讲解。核心技术篇首先分析了Struts2中多种具有代表性的设计模式,然后对Struts2中的精华——OGNL表达式引擎和XWork框架的原理及机制进行了全面深入的分析和讲解。运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值