James 7 年 前
コミット
8b61c41a65

+ 21 - 17
src/main/java/com/jfinal/aop/Aop.java

@@ -10,11 +10,11 @@ package com.jfinal.aop;
  * 
  * 
  * 3:Aop.inject(...) 与 Aop.get(...) 的区别是前者只针对传入的对象之中的属性进行注入。
  * 3:Aop.inject(...) 与 Aop.get(...) 的区别是前者只针对传入的对象之中的属性进行注入。
  *    而后者先要使用 Class 去创建对象,创建完对象以后对该对象之中的属性进行注入。
  *    而后者先要使用 Class 去创建对象,创建完对象以后对该对象之中的属性进行注入。
- *    简单一句话:get(...) 比 inject(...) 多了一个对象创建过程
+ *    简单一句话:get(...) 比 inject(...) 多了一个目标对象创建过程
  *    
  *    
- * 4:是否要 enhance 与 singleton 根据 Aop.setEhnace(...)、Aop.setSingleton(...) 配置来操作
+ * 4:是否要 singleton 与 enhance 根据 Aop.setSingleton(...)、Aop.setEhnace(...) 配置来操作
  * 
  * 
- * 5:在 @Inject(...) 指定 enhance 与 singleton 的配置可以覆盖掉默认配置
+ * 5:在目标类上使用注解 Singleton 与注解 Enhance 可以覆盖掉上面的默认配置
  * 
  * 
  * 
  * 
  * 基本用法:
  * 基本用法:
@@ -40,7 +40,7 @@ package com.jfinal.aop;
  * 2:只进行注入,对象自己创建
  * 2:只进行注入,对象自己创建
  *    Service srv = Aop.inject(new Service());
  *    Service srv = Aop.inject(new Service());
  *    srv.doIt();
  *    srv.doIt();
- *    Aop.injectd(...) 会对 OtherService otherSrv 进行注入,并且对 otherSrv 进行 ehnace,
+ *    Aop.inject(...) 会对 OtherService otherSrv 进行注入,并且对 otherSrv 进行 ehnace,
  *    所以 OtherService.doOther() 方法上的 Bbb 拦截器会生效
  *    所以 OtherService.doOther() 方法上的 Bbb 拦截器会生效
  *    
  *    
  * 3:创建对象并注入
  * 3:创建对象并注入
@@ -52,6 +52,9 @@ package com.jfinal.aop;
  * 4:以上两点中的 enhance 还取决于配置
  * 4:以上两点中的 enhance 还取决于配置
  *    Aop.setEnhance(false) 配置以后,只注入对象,但被注入对象不进行 enhance, Aaa、Bbb 拦截器都不会生效
  *    Aop.setEnhance(false) 配置以后,只注入对象,但被注入对象不进行 enhance, Aaa、Bbb 拦截器都不会生效
  *    
  *    
+ *    
+ * 注意:后续的 jfinal 3.6 版本将根据目标类是否配置了拦截器而进行增强,会去除一切与 enhance 有关的配置与代码
+ *      这里与 enhance 有关的配置仅为 jfinal 3.5 到 jfinal 3.6 的过渡
  * 
  * 
  * 
  * 
  * 
  * 
@@ -60,16 +63,17 @@ package com.jfinal.aop;
  *    @Inject(UserServiceImpl.class)			// 此处的 UserServiceImpl 为 UserService 的子类或实现类
  *    @Inject(UserServiceImpl.class)			// 此处的 UserServiceImpl 为 UserService 的子类或实现类
  *    UserService userService;
  *    UserService userService;
  * 
  * 
- * 2:被注入对象默认会被 enhance 增强,可以通过 Aop.setEnhance(false) 配置默认不增强
+ * 2:被注入对象默认是 singleton 单例,可以通过 Aop.setSingleton(false) 配置默认不为单例
  * 
  * 
- * 3:被注入对象默认是 singleton 单例,可以通过 Aop.setSingleton(false) 配置默认不为单例
+ * 3:被注入对象默认会被 enhance 增强,可以通过 Aop.setEnhance(false) 配置默认不增强
  * 
  * 
- * 4:可以在 @Inject 注解中直接配置 enhance 增强与 singleton 单例:
- *    @Inject(enhance=YesOrNo.NO, singleton=YesOrNo.YES)
- *    注意:如上在 @Inject 直接配置会覆盖掉 2、3 中 setEnhance()/setSingleton() 方法配置的默认值
+ * 4:可以在目标类中中直接配置注解 Singleton 与注解 Enhance:
+ *    @Singleton(false)
+ *    @Enhance(false) 
+ *    注意:如上在配置会覆盖掉 2、3 中 setSingleton()/setEnhance() 方法配置的默认值
  * 
  * 
- * 5:如上 2、3、4 中的配置,建议的用法是:先用 setEnhance()/setSingleton() 配置大多数情况,然后在个别
- *    违反上述配置的情况下在 @Inject 中直接 enhance、singleton 来覆盖默认配置,这样可以节省大量代码
+ * 5:如上 2、3、4 中的配置,建议的用法是:先用 /setSingleton()/setEnhance() 配置大多数情况,然后在个别
+ *    违反上述配置的情况下使用 Singleton 注解与 Enhance 注解来覆盖默认配置,这样可以节省大量代码
  */
  */
 public class Aop {
 public class Aop {
 	
 	
@@ -111,18 +115,18 @@ public class Aop {
 	}
 	}
 	
 	
 	/**
 	/**
-	 * 设置被注入的对象是否被增强,可使用 @Inject(enhance = YesOrNo.NO) 覆盖此默认值
+	 * 设置被注入的对象是否被增强,可使用 @Enhace(boolean) 覆盖此默认值
+	 * 
+	 * 由于下一版本的 jfinal 3.6 将根据目标类中是否存在 Before 注解
+	 * 来决定是否增强,所以该 setEnhance 方法仅仅是一个过渡功能,不建议使用
 	 */
 	 */
+	@Deprecated
 	public static void setEnhance(boolean enhance) {
 	public static void setEnhance(boolean enhance) {
 		aopFactory.setEnhance(enhance);
 		aopFactory.setEnhance(enhance);
 	}
 	}
 	
 	
-	public static boolean isEnhance() {
-		return aopFactory.isEnhance();
-	}
-	
 	/**
 	/**
-	 * 设置被注入的对象是否为单例,可使用 @Inject(singleton = YesOrNo.NO) 覆盖此默认值 
+	 * 设置被注入的对象是否为单例,可在目标类上使用 @Singleton(boolean) 覆盖此默认值 
 	 */
 	 */
 	public static void setSingleton(boolean singleton) {
 	public static void setSingleton(boolean singleton) {
 		aopFactory.setSingleton(singleton);
 		aopFactory.setSingleton(singleton);

+ 32 - 32
src/main/java/com/jfinal/aop/AopFactory.java

@@ -2,7 +2,6 @@ package com.jfinal.aop;
 
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Field;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentHashMap;
-import com.jfinal.aop.Enhancer;
 
 
 /**
 /**
  * AopFactory 是工具类 Aop 功能的具体实现,详细用法见 Aop
  * AopFactory 是工具类 Aop 功能的具体实现,详细用法见 Aop
@@ -12,10 +11,10 @@ public class AopFactory {
 	// 单例缓存
 	// 单例缓存
 	protected ConcurrentHashMap<Class<?>, Object> singletonCache = new ConcurrentHashMap<Class<?>, Object>();
 	protected ConcurrentHashMap<Class<?>, Object> singletonCache = new ConcurrentHashMap<Class<?>, Object>();
 	
 	
-	protected static int MAX_INJECT_DEPTH = 7;			// 最大注入深度 
+	protected static int MAX_INJECT_DEPTH = 7;			// 最大注入深度
 	
 	
-	protected YesOrNo enhance = YesOrNo.YES;				// 默认增强
-	protected YesOrNo singleton = YesOrNo.YES;			// 默认单例
+	protected boolean singleton = true;					// 默认单例
+	protected boolean enhance = true;					// 默认增强
 	protected int injectDepth = 3;						// 默认注入深度
 	protected int injectDepth = 3;						// 默认注入深度
 	
 	
 	@SuppressWarnings("unchecked")
 	@SuppressWarnings("unchecked")
@@ -24,9 +23,12 @@ public class AopFactory {
 			// Aop.get(obj.getClass()) 可以用 Aop.inject(obj),所以注掉下一行代码 
 			// Aop.get(obj.getClass()) 可以用 Aop.inject(obj),所以注掉下一行代码 
 			// targetClass = (Class<T>)getUsefulClass(targetClass);
 			// targetClass = (Class<T>)getUsefulClass(targetClass);
 			
 			
+			Singleton si = targetClass.getAnnotation(Singleton.class);
+			boolean singleton = (si != null ? si.value() : this.singleton);
+			
 			Object ret;
 			Object ret;
-			if (singleton == YesOrNo.NO) {
-				ret = createObject(targetClass, enhance);
+			if ( ! singleton ) {
+				ret = createObject(targetClass);
 				inject(targetClass, ret, injectDepth);
 				inject(targetClass, ret, injectDepth);
 				return (T)ret;
 				return (T)ret;
 			}
 			}
@@ -36,12 +38,13 @@ public class AopFactory {
 				synchronized (targetClass) {
 				synchronized (targetClass) {
 					ret = singletonCache.get(targetClass);
 					ret = singletonCache.get(targetClass);
 					if (ret == null) {
 					if (ret == null) {
-						ret = createObject(targetClass, enhance);
+						ret = createObject(targetClass);
 						inject(targetClass, ret, injectDepth);
 						inject(targetClass, ret, injectDepth);
 						singletonCache.put(targetClass, ret);
 						singletonCache.put(targetClass, ret);
 					}
 					}
 				}
 				}
 			}
 			}
+			
 			return (T)ret;
 			return (T)ret;
 		}
 		}
 		catch (ReflectiveOperationException e) {
 		catch (ReflectiveOperationException e) {
@@ -94,17 +97,10 @@ public class AopFactory {
 				fieldInjectedClass = field.getType();
 				fieldInjectedClass = field.getType();
 			}
 			}
 			
 			
-			YesOrNo enhance = inject.enhance();
-			if (enhance == YesOrNo.DEFAULT) {
-				enhance = this.enhance;
-			}
-			
-			YesOrNo singleton = inject.singleton();
-			if (singleton == YesOrNo.DEFAULT) {
-				singleton = this.singleton;
-			}
+			Singleton si = fieldInjectedClass.getAnnotation(Singleton.class);
+			boolean singleton = (si != null ? si.value() : this.singleton);
 			
 			
-			Object fieldInjectedObject = getOrCreateObject(fieldInjectedClass, enhance, singleton);
+			Object fieldInjectedObject = getOrCreateObject(fieldInjectedClass, singleton);
 			field.setAccessible(true);
 			field.setAccessible(true);
 			field.set(targetObject, fieldInjectedObject);
 			field.set(targetObject, fieldInjectedObject);
 			
 			
@@ -113,9 +109,9 @@ public class AopFactory {
 		}
 		}
 	}
 	}
 	
 	
-	protected Object getOrCreateObject(Class<?> targetClass, YesOrNo enhance, YesOrNo singleton) throws ReflectiveOperationException {
-		if (singleton == YesOrNo.NO) {
-			return createObject(targetClass, enhance);
+	protected Object getOrCreateObject(Class<?> targetClass, boolean singleton) throws ReflectiveOperationException {
+		if ( ! singleton ) {
+			return createObject(targetClass);
 		}
 		}
 		
 		
 		Object ret = singletonCache.get(targetClass);
 		Object ret = singletonCache.get(targetClass);
@@ -123,7 +119,7 @@ public class AopFactory {
 			synchronized (targetClass) {
 			synchronized (targetClass) {
 				ret = singletonCache.get(targetClass);
 				ret = singletonCache.get(targetClass);
 				if (ret == null) {
 				if (ret == null) {
-					ret = createObject(targetClass, enhance);
+					ret = createObject(targetClass);
 					singletonCache.put(targetClass, ret);
 					singletonCache.put(targetClass, ret);
 				}
 				}
 			}
 			}
@@ -135,8 +131,12 @@ public class AopFactory {
 	/**
 	/**
 	 * 由于上层已经处理过 singleton,所以 Enhancer.enhance() 方法中不必关心 singleton
 	 * 由于上层已经处理过 singleton,所以 Enhancer.enhance() 方法中不必关心 singleton
 	 */
 	 */
-	protected Object createObject(Class<?> targetClass, YesOrNo enhance) throws ReflectiveOperationException {
-		return (enhance == YesOrNo.YES) ? Enhancer.enhance(targetClass) : targetClass.newInstance();
+	@SuppressWarnings("deprecation")
+	protected Object createObject(Class<?> targetClass) throws ReflectiveOperationException {
+		Enhance en = targetClass.getAnnotation(Enhance.class);
+		boolean enhance = (en != null ? en.value() : this.enhance);
+		
+		return enhance ? com.jfinal.aop.Enhancer.enhance(targetClass) : targetClass.newInstance();
 	}
 	}
 	
 	
 	/**
 	/**
@@ -152,27 +152,27 @@ public class AopFactory {
 	}
 	}
 	
 	
 	/**
 	/**
-	 * 设置被注入的对象是否被增强,可使用 @Inject(enhance = YesOrNo.NO) 覆盖此默认值
+	 * 设置被注入的对象是否被增强,可使用 @Enhace(boolean) 覆盖此默认值
+	 * 
+	 * 由于下一版本的 jfinal 3.6 将根据目标类中是否配置了拦截器来决定是否增强,
+	 * 所以该 setEnhance 方法仅仅是一个过渡功能,不建议使用
 	 */
 	 */
+	@Deprecated
 	public AopFactory setEnhance(boolean enhance) {
 	public AopFactory setEnhance(boolean enhance) {
-		this.enhance = enhance ? YesOrNo.YES : YesOrNo.NO;
+		this.enhance = enhance;
 		return this;
 		return this;
 	}
 	}
 	
 	
-	public boolean isEnhance() {
-		return enhance == YesOrNo.YES;
-	}
-	
 	/**
 	/**
-	 * 设置被注入的对象是否为单例,可使用 @Inject(singleton = YesOrNo.NO) 覆盖此默认值 
+	 * 设置被注入的对象是否为单例,可使用 @Singleton(boolean) 覆盖此默认值 
 	 */
 	 */
 	public AopFactory setSingleton(boolean singleton) {
 	public AopFactory setSingleton(boolean singleton) {
-		this.singleton = singleton ? YesOrNo.YES : YesOrNo.NO;
+		this.singleton = singleton;
 		return this;
 		return this;
 	}
 	}
 	
 	
 	public boolean isSingleton() {
 	public boolean isSingleton() {
-		return singleton == YesOrNo.YES;
+		return singleton;
 	}
 	}
 	
 	
 	/**
 	/**

+ 21 - 0
src/main/java/com/jfinal/aop/Enhance.java

@@ -0,0 +1,21 @@
+package com.jfinal.aop;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Enhance 用于配置被注入对象是否要增强
+ * 
+ * 由于下一版本的 jfinal 3.6 将根据目标类中是否存在 Before 注解
+ * 来决定是否增强,所以该 Enhance 仅仅是一个过渡功能,不建议使用
+ */
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Deprecated
+public @interface Enhance {
+	boolean value();				// 是否增强
+}

+ 0 - 6
src/main/java/com/jfinal/aop/Inject.java

@@ -13,12 +13,6 @@ import java.lang.annotation.Target;
 @Retention(RetentionPolicy.RUNTIME)
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.FIELD})
 @Target({ElementType.FIELD})
 public @interface Inject {
 public @interface Inject {
-	
 	Class<?> value() default Void.class;					// 被注入类的类型
 	Class<?> value() default Void.class;					// 被注入类的类型
-	
-	YesOrNo enhance() default YesOrNo.DEFAULT;			// 是否增强
-	
-	YesOrNo singleton() default YesOrNo.DEFAULT;			// 是否单例
 }
 }
 
 
-

+ 17 - 0
src/main/java/com/jfinal/aop/Singleton.java

@@ -0,0 +1,17 @@
+package com.jfinal.aop;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Singleton 用于配置被注入对象是否为单例
+ */
+@Inherited
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+public @interface Singleton {
+	boolean value();				// 是否单例
+}

+ 0 - 14
src/main/java/com/jfinal/aop/YesOrNo.java

@@ -1,14 +0,0 @@
-package com.jfinal.aop;
-
-/**
- * YesOrNo 用于注解中的常量赋值,参考 Inject 注解的用法
- */
-public enum YesOrNo {
-	DEFAULT,		// 使用默认配置
-	YES,			// 用 YES 覆盖默认配置
-	NO			// 用 NO 覆盖默认配置
-}
-
-
-
-

+ 17 - 0
src/main/java/com/jfinal/config/Constants.java

@@ -146,6 +146,9 @@ final public class Constants {
 		return encoding;
 		return encoding;
 	}
 	}
 	
 	
+	/**
+	 * 设置自定义的 ControllerFactory 用于创建 Controller 对象
+	 */
 	public void setControllerFactory(ControllerFactory controllerFactory) {
 	public void setControllerFactory(ControllerFactory controllerFactory) {
 		if (controllerFactory == null) {
 		if (controllerFactory == null) {
 			throw new IllegalArgumentException("controllerFactory can not be null.");
 			throw new IllegalArgumentException("controllerFactory can not be null.");
@@ -153,6 +156,20 @@ final public class Constants {
 		this.controllerFactory = controllerFactory;
 		this.controllerFactory = controllerFactory;
 	}
 	}
 	
 	
+	/**
+	 * 设置为 AopControllerFactory 用于创建 Controller 对象并针对其中使用
+	 * Inject 注解的属性进行依赖注入。
+	 * 
+	 * 被注入对象默认为 singleton,可以通过 Aop.setSingleton(boolean) 配置
+	 * 该默认值。
+	 * 
+	 * 也可通过在被注入的目标类上使用 Singleton 注解覆盖上述默认值,注解配置
+	 * 优先级高于默认配置
+	 */
+	public void setToAopControllerFactory() {
+		this.controllerFactory = new com.jfinal.aop.AopControllerFactory();
+	}
+	
 	public ControllerFactory getControllerFactory() {
 	public ControllerFactory getControllerFactory() {
 		return controllerFactory;
 		return controllerFactory;
 	}
 	}

+ 7 - 0
src/main/java/com/jfinal/server/JFinalClassLoader.java

@@ -50,6 +50,13 @@ class JFinalClassLoader extends WebAppClassLoader {
 	@SuppressWarnings({"unchecked", "rawtypes"})
 	@SuppressWarnings({"unchecked", "rawtypes"})
 	public Class loadClass(String name) throws ClassNotFoundException {
 	public Class loadClass(String name) throws ClassNotFoundException {
 		try {
 		try {
+			
+			// 使用 WebAppContext.addSystemClass("sun.") 代替下面的方案更高效
+			// java.lang.IllegalAccessError: class sun.reflect.GeneratedConstructorAccessor2 cannot access its superclass sun.reflect.ConstructorAccessorImpl
+			// if (name.startsWith("sun.") || name.startsWith("com.sun.")) {
+				// return getParent().loadClass(name);
+			// }
+			
 			return loadClass(name, false);
 			return loadClass(name, false);
 		}
 		}
 		catch (NoClassDefFoundError e) {
 		catch (NoClassDefFoundError e) {

+ 4 - 0
src/main/java/com/jfinal/server/JettyServer.java

@@ -95,6 +95,10 @@ class JettyServer implements IServer {
 		connector.setPort(port);
 		connector.setPort(port);
 		server.addConnector(connector);
 		server.addConnector(connector);
 		webApp = new WebAppContext();
 		webApp = new WebAppContext();
+		
+		webApp.addSystemClass("sun.");
+		webApp.addSystemClass("com.sun.");
+		
 		webApp.setThrowUnavailableOnStartupException(true);	// 在启动过程中允许抛出异常终止启动并退出 JVM
 		webApp.setThrowUnavailableOnStartupException(true);	// 在启动过程中允许抛出异常终止启动并退出 JVM
 		webApp.setContextPath(context);
 		webApp.setContextPath(context);
 		webApp.setResourceBase(webAppDir);	// webApp.setWar(webAppDir);
 		webApp.setResourceBase(webAppDir);	// webApp.setWar(webAppDir);