xwork分析1

    技术2022-05-19  20

    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; } }

     

     


    最新回复(0)