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转成时间格式不匹配的错误