`

Struts2中的setDefaultLocale的实现

阅读更多

在struts2中可以在struts.properties文件中设置default local。如:struts.locale=zh_CN

查看源代码发现他是通过annotation Inject来设置的。

    @Inject(value=StrutsConstants.STRUTS_LOCALE, required=false)
    public static void setDefaultLocale(String val) {
        defaultLocale = val;
    }

    public static final String STRUTS_LOCALE = "struts.locale";

 接下来我们看一下它是怎么通过annotation来设置的呢。先调用addInjectorsForMembers()方法拿到有inject标签的方法,然后调用 injector.inject(context, null);方法。

 

 
void injectStatics(List<Class<?>> staticInjections) {
    final List<Injector> injectors = new ArrayList<Injector>();

    for (Class<?> clazz : staticInjections) {
      addInjectorsForFields(clazz.getDeclaredFields(), true, injectors);
      addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors);
    }

    callInContext(new ContextualCallable<Void>() {
      public Void call(InternalContext context) {
        for (Injector injector : injectors) {
          injector.inject(context, null);
        }
        return null;
      }
    });
  }

  void addInjectorsForFields(Field[] fields, boolean statics,
      List<Injector> injectors) {
    addInjectorsForMembers(Arrays.asList(fields), statics, injectors,
        new InjectorFactory<Field>() {
          public Injector create(ContainerImpl container, Field field,
              String name) throws MissingDependencyException {
            return new FieldInjector(container, field, name);
          }
        });
  }

//通过member.getAnnotation(Inject.class);方法拿到那些有Inject标签的方法,然后保存在
injectors里面。
  <M extends Member & AnnotatedElement> void addInjectorsForMembers(
      List<M> members, boolean statics, List<Injector> injectors,
      InjectorFactory<M> injectorFactory) {
    for (M member : members) {
      if (isStatic(member) == statics) {
        Inject inject = member.getAnnotation(Inject.class);
        if (inject != null) {
          try {
            injectors.add(injectorFactory.create(this, member, inject.value()));
          } catch (MissingDependencyException e) {
            if (inject.required()) {
              throw new DependencyException(e);
            }
          }
        }
      }
    }
  }

 然后在inject方法里面调用 method.invoke()方法,此处method是定义了inject的标签,此处是setDefaultLocale方法getParameters(method, context, parameterInjectors)返回参数,此处为‘zh_CN’。这样就通过反射设置进去了。

 public void inject(InternalContext context, Object o) {
      try {
        method.invoke(o, getParameters(method, context, parameterInjectors));
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
  }

 总结:此处涉及了两个方面,一是annotation的使用,二是反射的使用。这两个知识点都很常用。比如我上次做的为了减少struts的配置,用annotation标识那些类是Action类。struts.locale=zh_CN 中的配置应该和用户浏览器的配置一样,不然就会发生将string转成时间格式不匹配的错误

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics