1、开发一个类加载器来加载基础包名下的全部类,如使用了某注解的类,或者实现了某接口的类,又或者继承了某父类的全部子类(编写一个工具类,四个注解类)java
package org.smart4j.framework.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //控制器类上带有@Controller注解的类 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Controller { }
package org.smart4j.framework.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 服务层 * @author Admin * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Service { }
package org.smart4j.framework.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 依赖注入 * @author Admin * */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Inject { }
package org.smart4j.framework.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 控制器类上带有Action注解的方法( @Action("get:/customerEdit") ) * @author Admin * */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Action { /** * 请求类型与路径 */ String value(); }
1.一、须要写一个ClassUtil工具类,提供与类操做的相关方法,好比获取类加载器,加载类,获取指定包名下的全部类等等。apache
package org.smart4j.framework.util; import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.net.JarURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.smart4j.framework.helper.ConfigHelper; /** * 类操做工具类 * @author TS * */ public final class ClassUtil { private static final Logger LOGGER = LoggerFactory.getLogger(ClassUtil.class); /** * 获取当前线程中的类加载器 * @return ClassLoader对象 */ public static ClassLoader getClassLoader(){ return Thread.currentThread().getContextClassLoader(); } /** * 加载类 * @param className 类的全限定名 * @param isInitialied 是否初始化的标志(是否执行类的静态代码块)TODO * @return */ public static Class<?> loadClass(String className,boolean isInitialied){ Class<?> cls; try { cls = Class.forName(className, isInitialied, getClassLoader()); } catch (ClassNotFoundException e) { LOGGER.error("加载类初始化错误"); throw new RuntimeException(e); } return cls; } /** * 加载类 * @param className 类的全限定名 * @return */ public static Class<?> loadClass(String className){ Class<?> cls; try { cls = Class.forName(className); } catch (ClassNotFoundException e) { LOGGER.error("加载类初始化错误"); throw new RuntimeException(e); } return cls; } /** * 获取指定包名下的全部类 * @param packageName 包名 * @return Set<Class> * 1.根据包名将其转换为文件路径 * 2读取class或者jar包,获取指定的类名去加载类 */ public static Set<Class<?>> getClassSet(String packageName){ Set<Class<?>> classSet = new HashSet<Class<?>>(); try { Enumeration<URL> urls = getClassLoader().getResources(packageName.replace(".", "/")); if( urls.hasMoreElements() ){ URL url = urls.nextElement(); if(url != null ){ String protocol = url.getProtocol(); //协议名称 if( protocol.equals("file") ){ String packagePath = url.getPath().replace("%20", " "); //加载类 addClass(classSet,packagePath,packageName); }else if( protocol.equals("jar") ){ JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); if( jarURLConnection != null ){ JarFile jarFile = jarURLConnection.getJarFile(); if( jarFile != null ){ Enumeration<JarEntry> jarEntries = jarFile.entries(); while ( jarEntries.hasMoreElements() ) { JarEntry jarEntry = jarEntries.nextElement(); String jarEntryName = jarEntry.getName(); if( jarEntryName.endsWith(".class") ){ String className = jarEntryName.substring(0,jarEntryName.lastIndexOf(".")).replaceAll("/", "."); doAddClass(classSet,className); } } } } } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return classSet; } private static void addClass(Set<Class<?>> classSet, String packagePath, String packageName) { File[] files = new File(packagePath).listFiles(new FileFilter() { @Override public boolean accept(File file) { return ( file.isFile() && file.getName().endsWith(".class") ) || file.isDirectory(); } }); for (File file : files) { String fileName = file.getName(); System.out.println(fileName); if( file.isFile() ){ String className = fileName.substring( 0,fileName.lastIndexOf(".") ); if( StringUtils.isNotEmpty(packageName) ){ className = packageName + "." + className; } doAddClass(classSet, className); } else { String subPackagePath = fileName; if( StringUtils.isNotEmpty(packagePath) ){ subPackagePath = packagePath + "/" + subPackagePath; } String subPackageName = fileName; if( StringUtils.isNotEmpty(subPackageName) ){ subPackageName = packageName + "." + subPackageName; } addClass(classSet, subPackagePath, subPackageName); } } } private static void doAddClass(Set<Class<?>> classSet, String className) { Class<?> cls = loadClass(className, false); classSet.add(cls); } public static void main(String[] args) { ClassUtil.getClassSet(ConfigHelper.getAppBasePackage()); } }
1.二、在控制器类上添加@Controller注解框架
1.三、方法上添加@Action注解ide
1.四、在服务类上添加@Service注解工具
1.五、在控制器中@Inject注解将服务类依赖注入进来url
1.六、咱们在配置文件中指定了整个应用的基础包名(org.smart4j),经过ClassUtil工具加载的类都须要该基础包名。因此咱们还须要提供一个ClassHelper助手类,让他来获取应用包名下的全部类、应用包名下的全部Service类、应用包名下的全部Controller类。( ps:咱们能够将@Controller和@Service注解的类所产生的对象统一管理,能够理解为Smart框架所管理的全部Bean,因此还须要在ClassHelper类中增长一个获取应用包名下全部Bean类的方法)。.net
1.七、ClassHelper就完美封装了ClassUtil工具类,并提供了一系列助手方法,经过这些方法能够直接得到咱们想要的Class类对象的集合.开发者就能够ClassUtil 这个工具类了。线程
package org.smart4j.framework.helper; import java.util.HashSet; import java.util.Set; import org.smart4j.framework.annotation.Controller; import org.smart4j.framework.annotation.Service; import org.smart4j.framework.util.ClassUtil; /** * 类操做助手类 * @author TS * */ public final class ClassHelper { //获取应用下的全部Class类对象 //获取@Controller注解全部的Class类对象 //获取@Service注解全部的Class类对象 /** * 定义集合类( 存放所加载的类 ) */ private static final Set<Class<?>> CLASS_SET; static{ String basePackage = ConfigHelper.getAppBasePackage(); //配置文件基础包名 CLASS_SET = ClassUtil.getClassSet(basePackage); //加载全部类 } /** * 获取应用包名下的全部类 * @return */ public static Set<Class<?>> getClassSet(){ return CLASS_SET; } /** * 获取应用包名下的全部包含Service注解的类 * @return */ public static Set<Class<?>> getClassService(){ Set<Class<?>> classSet = new HashSet<Class<?>>(); for (Class<?> cls : CLASS_SET) { //遍历全部的Class类对象 if( cls.isAnnotationPresent( Service.class ) ){ //若是包含Service注解 classSet.add(cls); } } return classSet; } /** * 获取应用包名下的全部包含Controller注解的类 * @return */ public static Set<Class<?>> getClassController(){ Set<Class<?>> classSet = new HashSet<Class<?>>(); for (Class<?> cls : CLASS_SET) { //遍历全部的Class类对象 if( cls.isAnnotationPresent( Controller.class ) ){ //若是包含Service注解 classSet.add(cls); } } return classSet; } /** * 获取应用包名下的全部Bean类(包含:Controller、Service等) * @return */ public static Set<Class<?>> getBeanClassSet(){ Set<Class<?>> beanClassSet = new HashSet<Class<?>>(); beanClassSet.addAll( getClassService() ); beanClassSet.addAll( getClassController() ); return beanClassSet; } }
---------------------------------------summarize(总结):至此根据不一样类型的注解来获取指定的类对象( Class对象 )就大体编写完毕,后续会常常用到ClassHelper助手类。获得全部的Class对象之后,就要经过Class对象来实例化对象了,就是接下来的实现Bean容器。-----------------------------------------code