My favorites | Sign in
Project Logo
                
Search
for
Updated Aug 18, 2008 by pxb1988
DefaultFactoryBuilder  
DefaultFactoryBuilder

代码

/**
 *  Pxb IOC.
 *  Copyright 2008 Panxiaobo.
 *  All rights reserved.
 *  $Id: DefaultFactoryBuilder.java 35 2008-08-18 11:10:07Z Panxiaobo $
 */
package pxb.ioc.impl.builders;

import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import pxb.ioc.Context;
import pxb.ioc.Factory;
import pxb.ioc.ImplementedBy;
import pxb.ioc.Inject;
import pxb.ioc.InjectException;
import pxb.ioc.InstanceCreater;
import pxb.ioc.Key;
import pxb.ioc.Scope;
import pxb.ioc.ScopeFactory;
import pxb.ioc.ScopeNotFoundExcpetion;
import pxb.ioc.Scoped;
import pxb.ioc.builders.FactoryBuilder;
import pxb.ioc.builders.InstanceCreaterBuilder;
import pxb.ioc.managers.FactoryManager;

/**
 * @author Panxiaobo [pxb1988@126.com]
 */
public class DefaultFactoryBuilder implements FactoryBuilder
{
	protected ClassLoader				classLoader;
	protected Map<Class<?>, String>		clazzScops	= new HashMap<Class<?>, String>();
	protected FactoryManager			factoryManager;
	protected InstanceCreaterBuilder	instanceCreaterBuilder;
	protected Map<String, Scope>		scopes		= new HashMap<String, Scope>();

	public DefaultFactoryBuilder()
	{
		super();
		classLoader = this.getClass().getClassLoader();
	}

	public void addScope(String name, Scope scope)
	{
		this.scopes.put(name, scope);
	}

	/*
	 * (non-Javadoc)
	 * @see pxb.ioc.FactoryBuilder#buildFactory(pxb.ioc.FactoryManager,
	 * java.util.Map, pxb.ioc.Key)
	 */
	@SuppressWarnings("unchecked")
	public <T> Factory<T> buildFactory(Key<T> key, Class<? extends T> type)
			throws Exception
	{
		synchronized (type)
		{
			Factory<T> f = factoryManager.getFactory(key, false);
			if (f != null)
				return f;
			int modifiers = type.getModifiers();
			if (Modifier.isInterface(modifiers)
					|| Modifier.isAbstract(modifiers)
					|| !Modifier.isPublic(modifiers))
			{
				ImplementedBy implementedBy = type
						.getAnnotation(ImplementedBy.class);
				if (implementedBy == null)
				{
					throw new InjectException("No Maping Found For Key:" + key);
				}
				Class<?> clazz = classLoader.loadClass(implementedBy.value());
				type = (Class<T>) clazz;
			}
			String scopeName = this.clazzScops.get(type);
			if (scopeName == null)
			{
				Scoped scoped = type.getAnnotation(Scoped.class);
				scopeName = scoped == null ? Scope.DEFAULT : scoped.value();
			}
			Scope scope = scopes.get(scopeName);
			if (scope == null)
			{
				throw new ScopeNotFoundExcpetion(scopeName, type);
			}
			ScopeFactory<T> factory = scope.createFactory(key);
			// lock the factory
			synchronized (factory)
			{
				factoryManager.addFactory(key, factory);
				// just for test Thread safe
				// Thread.currentThread().sleep(1000);
				// InstanceCreater<T> instanceCreater = instanceCreaterBuilder
				// .buildInstanceCreater(type);
******************************************************************************
这里并不构造instnceCreater,而是构造了一个代理,真正掉用到的时候才构造
				InstanceCreater<T> instanceCreater = new ProxyInstanceCreater(
						factory, instanceCreaterBuilder, type);
*******************************************************************************
				factory.setInstanceCreater(instanceCreater);
			}
			return factory;
		}
	}

	private static class ProxyInstanceCreater<T> implements InstanceCreater<T>
	{
		private InstanceCreaterBuilder		instanceCreaterBuilder;
		private Class<T>					type;
		private volatile InstanceCreater<T>	instanceCreater;
		private ScopeFactory<T>				factory;

		public ProxyInstanceCreater(ScopeFactory<T> factory,
				InstanceCreaterBuilder instanceCreaterBuilder, Class<T> type)
		{
			this.factory = factory;
			this.instanceCreaterBuilder = instanceCreaterBuilder;
			this.type = type;
		}

		public synchronized void doCreate() throws Exception
		{
			if (this.instanceCreater == null)
			{//在这之前使用double checked lock
 //真正构造
				instanceCreater = instanceCreaterBuilder
						.buildInstanceCreater(type);
//设置给对应的factory,替代自己
				factory.setInstanceCreater(instanceCreater);
				this.factory = null;
			}
		}

		/*
		 * (non-Javadoc)
		 * @see pxb.ioc.InstanceCreater#create(pxb.ioc.Context)
		 */
		public T create(Context context) throws Exception
		{
			if (this.instanceCreater == null)
				this.doCreate();
			return instanceCreater.create(context);
		}

		/*
		 * (non-Javadoc)
		 * @see pxb.ioc.InstanceCreater#inject(pxb.ioc.Context,
		 * java.lang.Object)
		 */
		public void inject(Context context, T t) throws Exception
		{
			if (this.instanceCreater == null)
				this.doCreate();
			instanceCreater.inject(context, t);
		}
	}

	/**
	 * @param factoryManager
	 *            the factoryManager to set
	 */
	@Inject
	public void setFactoryManager(FactoryManager factoryManager)
	{
		this.factoryManager = factoryManager;
	}

	/**
	 * @param instanceCreaterBuilder
	 *            the instanceCreaterBuilder to set
	 */
	@Inject
	public void setInstanceCreaterBuilder(
			InstanceCreaterBuilder instanceCreaterBuilder)
	{
		this.instanceCreaterBuilder = instanceCreaterBuilder;
	}

	/*
	 * (non-Javadoc)
	 * @see pxb.ioc.builders.FactoryBuilder#setScope(java.lang.Class,
	 * java.lang.String)
	 */
	public void setScope(Class<?> type, String name)
	{
		this.clazzScops.put(type, name);
	}

}

Sign in to add a comment
Hosted by Google Code