Skip to content

Commit

Permalink
Fix issue #863
Browse files Browse the repository at this point in the history
  • Loading branch information
zozoh committed May 12, 2015
1 parent 6e5c146 commit b49a048
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 81 deletions.
20 changes: 3 additions & 17 deletions src/org/nutz/ioc/loader/annotation/AnnotationIocLoader.java
Expand Up @@ -24,7 +24,6 @@
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.resource.Scans;

/**
Expand All @@ -41,19 +40,8 @@ public class AnnotationIocLoader implements IocLoader {

public AnnotationIocLoader(String... packages) {
for (String packageZ : packages) {
// 启用动态路径
if (packageZ.equals("$dynamic")) {
String[] pkgs = Strings.splitIgnoreBlank(Mvcs.dynamic_ann_paths, "[,\n]");
if (null != pkgs)
for (String pkg : pkgs)
for (Class<?> classZ : Scans.me().scanPackage(pkg))
addClass(classZ);
}
// 否则老样子 ...
else {
for (Class<?> classZ : Scans.me().scanPackage(packageZ))
addClass(classZ);
}
for (Class<?> classZ : Scans.me().scanPackage(packageZ))
addClass(classZ);
}
if (map.size() > 0) {
if (log.isInfoEnabled())
Expand Down Expand Up @@ -176,9 +164,7 @@ protected void addClass(Class<?> classZ) {
continue;
// 过滤特殊方法
int m = method.getModifiers();
if (Modifier.isAbstract(m)
|| (!Modifier.isPublic(m))
|| Modifier.isStatic(m))
if (Modifier.isAbstract(m) || (!Modifier.isPublic(m)) || Modifier.isStatic(m))
continue;
String methodName = method.getName();
if (methodName.startsWith("set")
Expand Down
11 changes: 1 addition & 10 deletions src/org/nutz/lang/util/NutBean.java
Expand Up @@ -3,15 +3,8 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

public interface NutBean {

boolean containsKey(Object key);

Set<String> keySet();

Object remove(Object key);
public interface NutBean extends Map<String, Object> {

/**
* 设置一个字段,如果值为 null 则表示移除
Expand All @@ -23,8 +16,6 @@ public interface NutBean {
*/
void setOrRemove(String key, Object v);

Object get(Object key);

Object get(String key, Object dft);

int getInt(String key);
Expand Down
9 changes: 9 additions & 0 deletions src/org/nutz/mvc/ModuleScanner.java
@@ -0,0 +1,9 @@
package org.nutz.mvc;

import java.util.List;

public interface ModuleScanner {

List<Class<?>> scan();

}
13 changes: 1 addition & 12 deletions src/org/nutz/mvc/Mvcs.java
Expand Up @@ -36,16 +36,6 @@ public abstract class Mvcs {
public static final String MSG = "msg";
public static final String LOCALE_KEY = "nutz_mvc_localization_key";

// 这个全局变量用来为 AnnotationIocLoader 添加一个动态加载的包路径
// 如果 AnnotationIocLoader 的加载路径值为 $dynamic 则会将启用这个值
// 这个值可以是半角逗号或者换行符分隔的多个路径
public static String dynamic_ann_paths = null;

// 这个全局变量用来为 @Modules 添加一个动态模块加载路径
// 如果 @Module 的加载路径值为 $dynamic 则会将启用这个值
// 这个值可以是半角逗号或者换行符分隔的多个路径
public static String dynamic_modules = null;

// ====================================================================

public static Map<String, Object> getLocaleMessage(String key) {
Expand Down Expand Up @@ -176,8 +166,7 @@ public static void updateRequestAttributes(HttpServletRequest req) {
if (null != msgss) {
Map<String, Object> msgs = null;

String lKey = Strings.sBlank(Mvcs.getLocalizationKey(),
getDefaultLocalizationKey());
String lKey = Strings.sBlank(Mvcs.getLocalizationKey(), getDefaultLocalizationKey());

if (!Strings.isBlank(lKey))
msgs = msgss.get(lKey);
Expand Down
16 changes: 14 additions & 2 deletions src/org/nutz/mvc/annotation/Modules.java
Expand Up @@ -21,9 +21,10 @@
* 每个模块一个类
*/
Class<?>[] value() default {};

/**
* 需要扫描的package<p/>
* 需要扫描的package
* <p/>
* <b>这个属性不受scanPackage的影响!!</b>
*/
String[] packages() default {};
Expand All @@ -32,4 +33,15 @@
* 是否搜索模块类同包以及子包的其他类
*/
boolean scanPackage() default false;

/**
* 支持你实现一个模块加载器,然后
*
* <pre>
* @Modules(by={"ioc:myLoader", "com.my.app.MyModuleLoader"})
* </pre>
*
* @return 用哪些动态加载器加载模块
*/
String[] by() default {};
}
77 changes: 51 additions & 26 deletions src/org/nutz/mvc/impl/Loadings.java
Expand Up @@ -5,11 +5,11 @@
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.nutz.ioc.Ioc;
import org.nutz.ioc.annotation.InjectName;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
Expand All @@ -23,7 +23,7 @@
import org.nutz.mvc.ActionFilter;
import org.nutz.mvc.ActionInfo;
import org.nutz.mvc.HttpAdaptor;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.ModuleScanner;
import org.nutz.mvc.NutConfig;
import org.nutz.mvc.ObjectInfo;
import org.nutz.mvc.annotation.AdaptBy;
Expand Down Expand Up @@ -74,37 +74,63 @@ public static ActionInfo createInfo(Method method) {
return ai;
}

public static Set<Class<?>> scanModules(Class<?> mainModule) {
public static Set<Class<?>> scanModules(Ioc ioc, Class<?> mainModule) {
Modules ann = mainModule.getAnnotation(Modules.class);
boolean scan = null == ann ? false : ann.scanPackage();
// 准备扫描列表
List<Class<?>> list = new LinkedList<Class<?>>();
list.add(mainModule);
Set<Class<?>> forScans = new HashSet<Class<?>>();

// 准备存放模块类的集合
Set<Class<?>> modules = new HashSet<Class<?>>();

// 添加主模块,简直是一定的
forScans.add(mainModule);

// 根据配置,扩展扫描列表
if (null != ann) {
// 指定的类,这些类可以作为种子类,如果 ann.scanPackage 为 true 还要递归搜索所有子包
for (Class<?> module : ann.value()) {
list.add(module);
forScans.add(module);
}
}
// 扫描包
Set<Class<?>> modules = new HashSet<Class<?>>();
if (null != ann && ann.packages() != null && ann.packages().length > 0) {
for (String packageName : ann.packages()) {
// 启用动态路径
if (packageName.equals("$dynamic")) {
String[] pkgs = Strings.splitIgnoreBlank(Mvcs.dynamic_modules,
"[,\n]");
if (null != pkgs)
for (String pkg : pkgs) {
scanModuleInPackage(modules, pkg);
}

// 如果定义了扩展扫描接口 ...
for (String str : ann.by()) {
ModuleScanner ms;
// 扫描器来自 Ioc 容器
if (str.startsWith("ioc:")) {
String nm = str.substring("ioc:".length());
ms = ioc.get(ModuleScanner.class, nm);
}
// 否则老样子 ...
// 扫描器直接无参创建
else {
try {
Class<?> klass = Class.forName(str);
Mirror<?> mi = Mirror.me(klass);
ms = (ModuleScanner) mi.born();
}
catch (ClassNotFoundException e) {
throw Lang.wrapThrow(e);
}
}
// 执行扫描,并将结果计入搜索结果
List<Class<?>> list = ms.scan();
if (null != list)
for (Class<?> type : list) {
if (isModule(type)) {
modules.add(type);
}
}
}

// 扫描包,扫描出的类直接计入结果
if (ann.packages() != null && ann.packages().length > 0) {
for (String packageName : ann.packages()) {
scanModuleInPackage(modules, packageName);
}
}
}
for (Class<?> type : list) {

for (Class<?> type : forScans) {
// mawm 为了兼容maven,根据这个type来加载该type所在jar的加载
try {
URL location = type.getProtectionDomain().getCodeSource().getLocation();
Expand All @@ -116,8 +142,9 @@ public static Set<Class<?>> scanModules(Class<?> mainModule) {
}
Scans.me().registerLocation(type);
}

// 执行扫描
for (Class<?> type : list) {
for (Class<?> type : forScans) {
// 扫描子包
if (scan) {
scanModuleInPackage(modules, type.getPackage().getName());
Expand Down Expand Up @@ -257,10 +284,8 @@ public static void evalEncoding(ActionInfo ai, Encoding encoding) {
ai.setInputEncoding(org.nutz.lang.Encoding.UTF8);
ai.setOutputEncoding(org.nutz.lang.Encoding.UTF8);
} else {
ai.setInputEncoding(Strings.sNull(encoding.input(),
org.nutz.lang.Encoding.UTF8));
ai.setOutputEncoding(Strings.sNull(encoding.output(),
org.nutz.lang.Encoding.UTF8));
ai.setInputEncoding(Strings.sNull(encoding.input(), org.nutz.lang.Encoding.UTF8));
ai.setOutputEncoding(Strings.sNull(encoding.output(), org.nutz.lang.Encoding.UTF8));
}
}

Expand Down
32 changes: 18 additions & 14 deletions src/org/nutz/mvc/impl/NutLoading.java
Expand Up @@ -56,7 +56,7 @@ public UrlMapping load(NutConfig config) {
log.infof("Nutz.Mvc[%s] is initializing ...", config.getAppName());
}
if (log.isDebugEnabled()) {
Properties sys = System.getProperties();
Properties sys = System.getProperties();
log.debug("Web Container Information:");
log.debugf(" - Default Charset : %s", Encoding.defaultEncoding());
log.debugf(" - Current . path : %s", new File(".").getAbsolutePath());
Expand All @@ -65,9 +65,12 @@ public UrlMapping load(NutConfig config) {
log.debugf(" - Timezone : %s", sys.get("user.timezone"));
log.debugf(" - OS : %s %s", sys.get("os.name"), sys.get("os.arch"));
log.debugf(" - ServerInfo : %s", config.getServletContext().getServerInfo());
log.debugf(" - Servlet API : %d.%d", config.getServletContext().getMajorVersion(), config.getServletContext().getMinorVersion());
if (config.getServletContext().getMajorVersion() > 2 || config.getServletContext().getMinorVersion() > 4)
log.debugf(" - ContextPath : %s", config.getServletContext().getContextPath());
log.debugf(" - Servlet API : %d.%d",
config.getServletContext().getMajorVersion(),
config.getServletContext().getMinorVersion());
if (config.getServletContext().getMajorVersion() > 2
|| config.getServletContext().getMinorVersion() > 4)
log.debugf(" - ContextPath : %s", config.getServletContext().getContextPath());
}
/*
* 准备返回值
Expand Down Expand Up @@ -139,7 +142,8 @@ public UrlMapping load(NutConfig config) {

}

protected UrlMapping evalUrlMapping(NutConfig config, Class<?> mainModule, Ioc ioc) throws Exception {
protected UrlMapping evalUrlMapping(NutConfig config, Class<?> mainModule, Ioc ioc)
throws Exception {
/*
* @ TODO 个人建议可以将这个方法所涉及的内容转换到Loadings类或相应的组装类中,
* 以便将本类加以隔离,使本的职责仅限于MVC整体的初使化,而不再负责UrlMapping的加载
Expand Down Expand Up @@ -171,7 +175,7 @@ protected UrlMapping evalUrlMapping(NutConfig config, Class<?> mainModule, Ioc i
* 准备要加载的模块列表
*/
// TODO 为什么用Set呢? 用List不是更快吗?
Set<Class<?>> modules = Loadings.scanModules(mainModule);
Set<Class<?>> modules = Loadings.scanModules(ioc, mainModule);

if (modules.isEmpty()) {
if (log.isWarnEnabled())
Expand All @@ -195,7 +199,7 @@ protected UrlMapping evalUrlMapping(NutConfig config, Class<?> mainModule, Ioc i
ActionInfo info = Loadings.createInfo(method).mergeWith(moduleInfo);
info.setViewMakers(makers);
mapping.add(maker, info, config);
atMethods ++;
atMethods++;
}

// 记录pathMap
Expand All @@ -210,7 +214,7 @@ protected UrlMapping evalUrlMapping(NutConfig config, Class<?> mainModule, Ioc i
if (log.isWarnEnabled())
log.warn("None @At found in any modules class!!");
} else {
log.infof("Found %d module methods", atMethods);
log.infof("Found %d module methods", atMethods);
}

return mapping;
Expand Down Expand Up @@ -325,17 +329,17 @@ protected ViewMaker[] createViewMakers(Class<?> mainModule, Ioc ioc) throws Exce
List<ViewMaker> makers = new ArrayList<ViewMaker>();
if (null != vms) {
for (int i = 0; i < vms.value().length; i++) {
if (vms.value()[i].getAnnotation(IocBean.class) != null && ioc != null) {
makers.add(ioc.get(vms.value()[i]));
} else {
makers.add(Mirror.me(vms.value()[i]).born());
}
if (vms.value()[i].getAnnotation(IocBean.class) != null && ioc != null) {
makers.add(ioc.get(vms.value()[i]));
} else {
makers.add(Mirror.me(vms.value()[i]).born());
}
}
} else {
if (ioc != null) {
String[] names = ioc.getNames();
Arrays.sort(names);
for(String name: ioc.getNames()) {
for (String name : ioc.getNames()) {
if (name != null && name.startsWith(ViewMaker.IOCNAME)) {
log.debug("add ViewMaker from Ioc by name=" + name);
makers.add(ioc.get(ViewMaker.class, name));
Expand Down

0 comments on commit b49a048

Please sign in to comment.