package com.taobao.easyweb.core.groovy.groovyobject; import com.taobao.easyweb.core.app.App; import com.taobao.easyweb.core.app.AppLogger; import com.taobao.easyweb.core.bean.BeanFactory; import com.taobao.easyweb.core.groovy.BeanBinding; import com.taobao.easyweb.core.groovy.MethodInterceptor; import com.taobao.easyweb.core.groovy.annotation.AnnotationParser; import com.taobao.easyweb.core.groovy.annotation.AnnotationParserFactory; import com.taobao.easyweb.core.request.Page; import com.taobao.easyweb.core.velocity.GroovyVelocityEngine; import groovy.lang.*; import org.apache.log4j.Logger; import org.codehaus.groovy.reflection.CachedMethod; import org.codehaus.groovy.runtime.InvokerHelper; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.beans.IntrospectionException; import java.io.File; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.List; /** * User: jimmey/shantong * DateTime: 13-4-24 ����12:07 * <p/> * groovy��������࣬�;����classloader����������classloader����ļ������Ͷ�Ӧ */ @Component public class GroovyObjectLoader { @Resource(name = "ewMethodInterceptor") private MethodInterceptor methodInterceptor; @Resource(name = "ewBinding") private BeanBinding binding; @Resource(name = "ewGroovyVelocityEngine") private GroovyVelocityEngine groovyVelocityEngine; /** * ʵ����app��biz�µ����ж��� * * @param webClass �Ƿ���web groovy����������������ȡweb classloader����biz classloader * @param app * @param file */ public void instanceObject(boolean webClass, App app, File file) { GroovyClassLoader classLoader = getByType(webClass, app); CacheDO cacheDO = Cacher.get(classLoader, file); if (cacheDO == null) { Logger logger = AppLogger.getAppLogger(app.getAppKey(), "ClassLoader"); try { Class<?> clazz = null; if (webClass) {//��Ӧ���ֲ�ͬ��load��ʽ try { GroovyCodeSource codeSource = new GroovyCodeSource(file, "GBK"); clazz = AppClassLoaderFactory.getAppWebClassLoader(app).parseClass(codeSource, false); } catch (Exception e) { e.printStackTrace(); logger.error(e); } } else { clazz = classLoader.loadClass(FileMainClass.get(file.getAbsolutePath())); } GroovyObject obj = (GroovyObject) clazz.newInstance(); parseAnnotation(AnnotationParser.ParsePhase.Init, app, file, obj); cacheDO = new CacheDO(); cacheDO.setLastModified(file.lastModified()); cacheDO.setObj(obj); cacheDO.setAutowired(false); Cacher.put(classLoader, file, cacheDO); } catch (ClassNotFoundException e) { logger.error(e); } catch (InstantiationException e) { logger.error(e); } catch (IllegalAccessException e) { logger.error(e); } } } public void autowiredObject(boolean webClass, App app, File file) { GroovyClassLoader classLoader = getByType(webClass, app); CacheDO cacheDO = Cacher.get(classLoader, file); if (cacheDO == null) { return; } GroovyObject object = cacheDO.getObj(); binding.setProperty("vm", groovyVelocityEngine); binding.setProperty("log", AppLogger.getLogger("GroovyScript")); if (object instanceof Script) { Script script = (Script) object; script.setBinding(binding); } else { InvokerHelper.setProperties(object, binding.getVariables()); InvokerHelper.setProperties(object, BeanFactory.getBeans(app)); } if (app != null) { parseAnnotation(AnnotationParser.ParsePhase.Ioc, app, file, object); } MetaClassProxy proxy; try { proxy = MetaClassProxy.getMyInstance(object.getClass()); } catch (IntrospectionException e) { throw new RuntimeException(e); } proxy.setInterceptor(methodInterceptor); object.setMetaClass(proxy); cacheDO.setAutowired(true); } public GroovyObject getObject(boolean webClass, App app, File file) { GroovyClassLoader classLoader = getByType(webClass, app); CacheDO cacheDO = Cacher.get(classLoader, file); if (cacheDO == null) {//���û�У���ִ��һ�� instanceObject(webClass, app, file); autowiredObject(webClass, app, file); } else if (cacheDO.isAutowired()) { autowiredObject(webClass, app, file); } cacheDO = Cacher.get(classLoader, file); return cacheDO.getObj(); } private GroovyClassLoader getByType(boolean webClass, App app) { if (webClass) { return AppClassLoaderFactory.getAppWebClassLoader(app); } else { return AppClassLoaderFactory.getAppBizClassLoader(app); } } private void parseAnnotation(AnnotationParser.ParsePhase parsePhase, App app, File file, GroovyObject object) { if (object instanceof Script) { Script script = (Script) object; List<MetaMethod> metaMethods = script.getMetaClass().getMethods(); for (MetaMethod method : metaMethods) { if (method instanceof CachedMethod) { Method javaMethod = ((CachedMethod) method).getCachedMethod(); Annotation[] annotations = javaMethod.getAnnotations(); for (Annotation annotation : annotations) { AnnotationParserFactory.parse(parsePhase, app, annotation, file, javaMethod, object); } } } } else { Annotation[] annotations = object.getClass().getAnnotations(); for (Annotation annotation : annotations) { AnnotationParserFactory.parse(parsePhase, app, annotation, file, object.getClass(), object); } Method[] methods = object.getClass().getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(Page.class)) { Annotation[] ans = method.getAnnotations(); for (Annotation annotation : ans) { AnnotationParserFactory.parse(parsePhase, app, annotation, file, method, object); } } } Field[] fields = object.getClass().getDeclaredFields(); for (Field field : fields) { Annotation[] ans = field.getAnnotations(); for (Annotation annotation : ans) { AnnotationParserFactory.parse(parsePhase, app, annotation, file, field, object); } } } } }