本人小菜一枚,表达能力也不是很好,哪里写了不好的地方请大神评论下。
首先写Controller对映的注解,这里我将其命名为C
这个注解现在比较简单些
net.zz.annotation; java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @C { String value(); }
首先写Model对映的注解,这里我将其命名为M这个注解现在也是比较简单些,呵呵!
net.zz.annotation; java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Documented @M { String value() ;String id() ; }
注解写好了,接下来得写一个对类的扫描器.这里我写了也比较简单,主要只是为了实现这个Demo
net.zz.plugin; javax.servlet.http.HttpServletRequest; java.io.File; java.io.FileFilter; java.io.IOException; java.net.JarURLConnection; java.net.URL; java.net.URLDecoder; java.util.Enumeration; java.util.LinkedHashSet; java.util.Set; java.util.jar.JarEntry; java.util.jar.JarFile; Scan { HttpServletRequest request; Scan() { } Scan(HttpServletRequest request) { .request = request; } Set<Class<?>> getClasses(String pack) { Set<Class<?>> classes = LinkedHashSet<Class<?>>(); recursive = ; String packageName = pack; String packageDirName = packageName.replace(, ); Enumeration<URL> dirs; { dirs = Thread.currentThread().getContextClassLoader().getResources( packageDirName); (dirs.hasMoreElements()) { URL url = dirs.nextElement(); String protocol = url.getProtocol(); (.equals(protocol)) { String filePath = URLDecoder.decode(url.getFile(), ); findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes); } (.equals(protocol)) { JarFile jar; { jar = ((JarURLConnection) url.openConnection()) .getJarFile(); Enumeration<JarEntry> entries = jar.entries(); (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); (name.charAt() == ) { name = name.substring(); } (name.startsWith(packageDirName)) { idx = name.lastIndexOf(); (idx != -) { packageName = name.substring(, idx) .replace(, ); } ((idx != -) || recursive) { (name.endsWith() && !entry.isDirectory()) { String className = name.substring( packageName.length() + , name .length() - ); { classes.add(Class .forName(packageName + + className)); } (ClassNotFoundException e) { e.printStackTrace(); } } } } } } (IOException e) { e.printStackTrace(); } } } } (IOException e) { e.printStackTrace(); } classes; } findAndAddClassesInPackageByFile(String packageName, String packagePath, recursive, Set<Class<?>> classes) { File dir = File(packagePath); (!dir.exists() || !dir.isDirectory()) { ; } File[] dirfiles = dir.listFiles(FileFilter() { accept(File file) { (recursive && file.isDirectory()) || (file.getName().endsWith()); } }); (File file : dirfiles) { (file.isDirectory()) { findAndAddClassesInPackageByFile(packageName + + file.getName(), file.getAbsolutePath(), recursive, classes); } { String className = file.getName().substring(, file.getName().length() - ); { Class<?> cls=Thread.currentThread().getContextClassLoader().loadClass(packageName + + className); classes.add(cls); } (ClassNotFoundException e) { e.printStackTrace(); } } } } getName(String path) { File file = File(path); (file.isDirectory()) { File[] dirFile = file.listFiles(); (File f : dirFile) { (f.isDirectory()) getName(f.getAbsolutePath()); { (f.getName().endsWith()) System.out.println(f.getAbsolutePath()); } } } } }
这个简单的扫描起就这样写完了,接下来就是最重要的JFinal配置的部分,实现注解处理适配的部分
编写一个抽象类JFinalConfig,这个配置类跟之前写的差不多,我们继承com.jfinal.config.JFinalConfig这个类,并实现下面这几个方法
public void configRoute(Routes me) public void configPlugin(Plugins me) 编写三个抽象方法
controlSscan(List<String> controlPackage); componentSscan(List<String> basePackage); IDataSourceProvider setDataSource ();controlSscan方法主要用于设置controller的扫描,componentSscan也是一样的意思。setDataSource 这个方法配置数据源。接下来一个是用于开发者进行需要时覆盖的方法,用于活动记录的插件添加addActiveRecord(ActiveRecordPlugin arp){}下面是对应的具体代码。net.zz.config; com.jfinal.config.*; com.jfinal.core.Controller; com.jfinal.plugin.IPlugin; com.jfinal.plugin.activerecord.ActiveRecordPlugin; com.jfinal.plugin.activerecord.IDataSourceProvider; com.jfinal.plugin.activerecord.Model; com.jfinal.plugin.c3p0.C3p0Plugin; net.zz.annotation.C; net.zz.annotation.M; net.zz.plugin.Scan; java.util.ArrayList; java.util.List; java.util.Set; JFinalConfig com.jfinal.config.JFinalConfig{ List<String> controlPackage = ArrayList<String>(); List<String> basePackage = ArrayList<String>(); controlSscan(List<String> controlPackage); componentSscan(List<String> basePackage); IDataSourceProvider setDataSource (showSql); @Override configRoute(Routes me) { controlSscan(controlPackage);Scan driven = Scan(); (String pake : controlPackage){ Set<Class<?>> clazzs = driven.getClasses(pake); (Class<?> clazz : clazzs) { System.out.println(clazz.getName()); (clazz.isAssignableFrom(com.jfinal.core.Controller.)) { C con = clazz.getAnnotation(C.); (!= con) { me.add(con.value(), (Class<? Controller>) clazz); } } } } } @Override configPlugin(Plugins me) { componentSscan(basePackage); IDataSourceProvider iDataSourceProvider = setDataSource(); { me.add((IPlugin) iDataSourceProvider); }(Exception e){ RuntimeException(); } ActiveRecordPlugin arp = ActiveRecordPlugin(iDataSourceProvider); addActiveRecord(arp); Scan driven = Scan(); (String pake : controlPackage){ Set<Class<?>> clazzs = driven.getClasses(pake); (Class<?> clazz : clazzs) { System.out.println(clazz.getName()); (clazz.isAssignableFrom(com.jfinal.plugin.activerecord.Model.)) { M model = clazz.getAnnotation(M.); (!= model) { arp.addMapping(model.value(), model.id(), (Class<? Model<?>>) clazz); } } } } me.add(arp); } addActiveRecord(ActiveRecordPlugin arp){ // arp.setShowSql(true);//设置是sql显示开关 } }
接下来是简单实现Config配置的例子
package net.zz.config; import com.jfinal.plugin.activerecord.IDataSourceProvider; import net.mzzo.inter.JsonCrossDomain; import net.mzzo.inter.Login; import com.jfinal.config.Constants; import com.jfinal.config.Handlers; import com.jfinal.config.Interceptors; import com.jfinal.plugin.c3p0.C3p0Plugin; import net.zz.config.JFinalConfig; import java.util.List; public class ZZConfig extends JFinalConfig { public void configConstant(Constants me) { loadPropertyFile("config.properties"); me.setDevMode(getPropertyToBoolean("devMode", false)); } public void configHandler(Handlers me) { } @Override public void controlSscan(List<String> list) { list.add("net.zz.controler"); list.add("net.zz.util"); } @Override public void componentSscan(List<String> list) { list.add("net.mzzo.model"); } @Override public IDataSourceProvider setDataSource() { showSql = true; C3p0Plugin c3p0Plugin = new C3p0Plugin(getProperty("jdbcUrl"), getProperty("user"), getProperty("password"), getProperty("driverClass"), getPropertyToInt("maxPoolSize"), getPropertyToInt("minPoolSize"), getPropertyToInt("initialPoolSize"), getPropertyToInt("maxIdleTime"), getPropertyToInt("acquireIncrement")); return c3p0Plugin; } public void configInterceptor(Interceptors me) { me.add(new JsonCrossDomain()); me.add(new Login()); } }
//接下来就是Controller的例子 @C("/users") public class UsersControl extends Controller { }
下面就是Model的例子 @M("users") public class Users extends Model<Users> { } 再次说下表达不是很好。 接下来的想法是将JFinal的Model部分稍微包装一下,github地址:https://github.com/cnzzs/zjf
时间: 2024-10-13 11:47:02