天天看点

xwork分析1

import java.util.HashMap;

import java.util.Map;

import com.opensymphony.xwork2.ActionProxy;

import com.opensymphony.xwork2.ActionProxyFactory;

import com.opensymphony.xwork2.config.Configuration;

import com.opensymphony.xwork2.config.ConfigurationManager;

import com.opensymphony.xwork2.inject.Container;

public class Main {

public static void main(String args[]){

ConfigurationManager cm = new ConfigurationManager();//1

Configuration config = cm.getConfiguration();//2

Container c = config.getContainer();//3

ActionProxyFactory actionProxyFactory = c.getInstance(ActionProxyFactory.class);//4

Map<String,Object> m = new HashMap<String,Object>();//5

m.put("name", "bobo");

ActionProxy actionProxy = actionProxyFactory.createActionProxy(

"/helloWorld", "actionTest",null, m);//6

try {

actionProxy.execute();//7

} catch (Exception e) {

e.printStackTrace();

}

}

}

1 . ConfigurationManager,这个是xwork配置管理的核心,它默认是读取xwork.xml的配置文件的信息,xwork.xml可以通过extends="xwork-default" 来继承xwork-default.xml的配置信息,可以使用里面定义的各种拦截器,ConfigurationManager的主要内容如下:

 public class ConfigurationManager {

protected Configuration configuration;//相关的配置信息

protected Lock providerLock = new ReentrantLock();//获取/设置containerProviders时使用的锁

private List<ContainerProvider> containerProviders = new CopyOnWriteArrayList<ContainerProvider>();//为容器提供bean,constants/properties信息

private List<PackageProvider> packageProviders = new CopyOnWriteArrayList<PackageProvider>();//提供包配置信息 TODO

protected String defaultFrameworkBeanName;

public ConfigurationManager() {

this("xwork");

}

public ConfigurationManager(String name) {

this.defaultFrameworkBeanName = name;

}

public List<ContainerProvider> getContainerProviders() {

providerLock.lock();

try {

//没有提供的话就默认使用一下2个provider

if (containerProviders.size() == 0) {

containerProviders.add(new XWorkConfigurationProvider());

containerProviders.add(new XmlConfigurationProvider("xwork.xml", false));

}

return containerProviders;

} finally {

providerLock.unlock();

}

}

public synchronized Configuration getConfiguration() {

if (configuration == null) {

//第一次获取的时候会初始化所有相关的ContainerProvider

setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));

try {

configuration.reloadContainer(getContainerProviders());

} catch (ConfigurationException e) {

setConfiguration(null);

throw new ConfigurationException("Unable to load configuration.", e);

}

} else {

conditionalReload();

}

return configuration;

}

}

2.Configuration是xwork的配置信息,它是一个接口主要的实现类有2个DefaultConfiguration和MockConfiguration(单元测试用的),Configuration的主要内容如下:

public interface Configuration extends Serializable {

PackageConfig getPackageConfig(String name);//取得某一个package的配置信息

Map<String, PackageConfig> getPackageConfigs();//取得所有package的配置信息

RuntimeConfiguration getRuntimeConfiguration();//取得运行时期的配置信息

void addPackageConfig(String name, PackageConfig packageConfig);//添加包配置信息

PackageConfig removePackageConfig(String packageName);//移除包配置信息

Container getContainer();//获得容器

Set<String> getLoadedFileNames();//获得加载的配置文件的信息

}

 DefaultConfiguration是Configuration的实现类,它的主要成员变量有:

public class DefaultConfiguration implements Configuration {

//相关的信息都存储在以下的成员变量中---------

protected Map<String, PackageConfig> packageContexts = new LinkedHashMap<String, PackageConfig>();

protected RuntimeConfiguration runtimeConfiguration;

protected Container container;

protected String defaultFrameworkBeanName;

protected Set<String> loadedFileNames = new TreeSet<String>();

protected List<UnknownHandlerConfig> unknownHandlerStack;

//xwork提供的对象创建工厂,使用buildBean 来创建所有的类,用户可以自定义自己的ObjectFactory

ObjectFactory objectFactory;

}

DefaultConfiguration的主要责任就是在reloadContainer的时候根据注册的所有ConfigurationProvider的提供的信息来实例化一个Container(它的默认实现是ContainerImpl),然后根据Container来实例化ObjectFactory,最后使用Container对各个ConfigurationProvider进行依赖注入

public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {

packageContexts.clear();

loadedFileNames.clear();

List<PackageProvider> packageProviders = new ArrayList<PackageProvider>();

//在取得xwork的配置信息的时候使用了2个类从各个Providers取得相应的信息

ContainerProperties props = new ContainerProperties();

ContainerBuilder builder = new ContainerBuilder();

for (final ContainerProvider containerProvider : providers)

{

containerProvider.init(this);

containerProvider.register(builder, props);//各个provider在register的时候往这2个实例中放入配置参数

}

props.setConstants(builder);

builder.factory(Configuration.class, new Factory<Configuration>() {

public Configuration create(Context context) throws Exception {

return DefaultConfiguration.this;

}

});

ActionContext oldContext = ActionContext.getContext();

try {

// Set the bootstrap container for the purposes of factory creation

Container bootstrap = createBootstrapContainer();

setContext(bootstrap);

container = builder.create(false);

setContext(container);

objectFactory = container.getInstance(ObjectFactory.class);

// Process the configuration providers first

for (final ContainerProvider containerProvider : providers)

{

if (containerProvider instanceof PackageProvider) {

container.inject(containerProvider);

((PackageProvider)containerProvider).loadPackages();

packageProviders.add((PackageProvider)containerProvider);

}

}

// Then process any package providers from the plugins

Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);

if (packageProviderNames != null) {

for (String name : packageProviderNames) {

PackageProvider provider = container.getInstance(PackageProvider.class, name);

provider.init(this);

provider.loadPackages();

packageProviders.add(provider);

}

}

rebuildRuntimeConfiguration();

} finally {

if (oldContext == null) {

ActionContext.setContext(null);

}

}

return packageProviders;

}  

ContainerBuilder是一个final类,它主要是存储有关类型和相关实现类的信息,它主要的成员变量和方法有:

public final class ContainerBuilder {

final Map<Key<?>, InternalFactory<?>> factories =

new HashMap<Key<?>, InternalFactory<?>>();//所有class和name对应的实现类

final List<InternalFactory<?>> singletonFactories =

new ArrayList<InternalFactory<?>>();//所有的单例的实现类

final List<Class<?>> staticInjections = new ArrayList<Class<?>>();//配置中bean中static=true的类

boolean created;//是否已经创建,适用于单例模式

boolean allowDuplicates = false;

/**

* 添加映射

*/

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;

}

/**

*创建Container

*/

public Container create(boolean loadSingletons) {

ensureNotCreated();

created = true;

final ContainerImpl container = new ContainerImpl(

new HashMap<Key<?>, InternalFactory<?>>(factories));

if (loadSingletons) {

container.callInContext(new ContainerImpl.ContextualCallable<Void>() {

public Void call(InternalContext context) {

for (InternalFactory<?> factory : singletonFactories) {

factory.create(context);

}

return null;

}

});

}

container.injectStatics(staticInjections);

return container;

}

}