转载

【JAVA实例】自己动手实现IOC和MVC(二)

上一节介绍了一些spring基本知识 和 实现ioc的思路 ,下面按照整个思路一步步来完成咱们自己的ioc framework 在instance你annotation的class和inject属性的时候,首先你要扫描的你配置的package以及package子包下的所有class是否标注有annotation(如:@Repository,@Service,@Controller) 这里有几个问题? ①怎么定义Java annotation? 这里我要模仿spring定义四个java annotation 用于你dao层、service层 、action层用于标注你各层的bean 以及用于inject属性的java annotation Dao.java
  1. package com.ajunframework.beans.annotation;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Inherited;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. /**
  9.  * 应用于dao层实例化
  10.  * @author harries
  11.  * @http://www.liuhaihua.cn
  12.  */
  13. @Target(ElementType.TYPE)
  14. @Retention(RetentionPolicy.RUNTIME)
  15. @Documented
  16. @Inherited
  17. public @interface Dao {
  18.     public String value() default "";
  19. }
Service.java
  1. package com.ajunframework.beans.annotation;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Inherited;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. import com.ajunframework.beans.constant.BeanScop;
  9. /**
  10.  * 实例化service
  11.  * @author harries
  12.  * @http://www.liuhaihua.cn
  13.  */
  14. @Target(ElementType.TYPE)
  15. @Retention(RetentionPolicy.RUNTIME)
  16. @Documented
  17. @Inherited
  18. public @interface Service {
  19.     public String value() default “”;
  20. }
 Action.java
  1. package com.ajunframework.beans.annotation;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Inherited;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. /**
  9.  * 应用在action 实例化
  10.  * @author harries
  11.  * @http://www.liuhaihua.cn
  12.  */
  13. @Target(ElementType.TYPE)
  14. @Retention(RetentionPolicy.RUNTIME)
  15. @Documented
  16. @Inherited
  17. public @interface Action {
  18.     public String value() default "";
  19. }
Property.java
  1. package com.ajunframework.beans.annotation;
  2. import java.lang.annotation.Documented;
  3. import java.lang.annotation.ElementType;
  4. import java.lang.annotation.Inherited;
  5. import java.lang.annotation.Retention;
  6. import java.lang.annotation.RetentionPolicy;
  7. import java.lang.annotation.Target;
  8. /**
  9.  * 进行依赖注入
  10.  * @author ajun
  11.  * @http://blog.csdn.net/ajun_studio
  12.  */
  13. @Target(ElementType.FIELD)
  14. @Retention(RetentionPolicy.RUNTIME)
  15. @Documented
  16. @Inherited
  17. public @interface Property {
  18.     public String value() default "";
  19. }
 
②怎么扫描? 这里提供一个用于扫描package以及package子包下的所有class PackageUtils.java
  1. package com.ajunframework.beans.utils;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.net.URL;
  5. import java.util.ArrayList;
  6. import java.util.Enumeration;
  7. import java.util.List;
  8. /**
  9.  * @authorharries
  10.  * @http://www.liuhaihua.cn
  11.  */
  12. public class PackageUtils {
  13.     /**
  14.      * 扫描给定包及子包内的所有类
  15.      * 
  16.      * @param packageName
  17.      *            给定的包名
  18.      * @return The classes
  19.      * @throws ClassNotFoundException
  20.      * @throws IOException
  21.      */
  22.     @SuppressWarnings("unchecked")
  23.     public static Class[] getClasses(String packageName)
  24.             throws ClassNotFoundException, IOException {
  25.         Class cla = PackageUtils.class;
  26.         String path = packageName.replace('.''/');
  27.         Enumeration<URL> resources = cla.getClassLoader().getResources(path);
  28.         List<File> dirs = new ArrayList<File>();
  29.         while (resources.hasMoreElements()) {
  30.             URL resource = resources.nextElement();
  31.             dirs.add(new File(resource.getFile()));
  32.         }
  33.         ArrayList<Class> classes = new ArrayList<Class>();
  34.         for (File directory : dirs) {
  35.             classes.addAll(findClasses(directory, packageName));
  36.         }
  37.         return classes.toArray(new Class[classes.size()]);
  38.     }
  39.     /**
  40.      * 找到制定包内的所有class文件
  41.      * 
  42.      * @param directory
  43.      *            目录名称
  44.      * @param packageName
  45.      *            包名称
  46.      * @return The classes
  47.      * @throws ClassNotFoundException
  48.      */
  49.     @SuppressWarnings("unchecked")
  50.     private static List<Class> findClasses(File directory, String packageName)
  51.             throws ClassNotFoundException {
  52.         List<Class> classes = new ArrayList<Class>();
  53.         if (!directory.exists()) {
  54.             return classes;
  55.         }
  56.         File[] files = directory.listFiles();
  57.         for (File file : files) {
  58.             if (file.isDirectory()) {
  59.                 classes.addAll(findClasses(file,
  60.                         packageName + "." + file.getName()));
  61.             } else if (file.getName().endsWith(".class")) {
  62.                 classes.add(Class.forName(packageName
  63.                         + '.'
  64.                         + file.getName().substring(0,
  65.                                 file.getName().length() - 6)));
  66.             }
  67.         }
  68.         return classes;
  69.     }
  70.     /**
  71.      * @throws IOException
  72.      * @throws ClassNotFoundException
  73.      * 
  74.      */
  75. //  public static void main(String[] args) throws Exception {
  76. //      Class[] clas = PackageUtils.getClassess("com.ajunframework.utils");
  77. //      for (Class cla : clas) {
  78. //          System.out.println(cla.getName());
  79. //      }
  80. //  }
  81. }
扫描的路径怎么传入呢 ?这里可以定义一个properties文件 用于定义一些常量 constant.properties
  1. scan-package=com.ajun.test #这里是你要的package的路径
下面可以提供一个读取constant.properties文件 ,供外包调用返回class[]数组的工具类 ScanClass.java
  1. package com.ajunframework.beans.scan;
  2. import java.io.IOException;
  3. import com.ajunframework.beans.utils.PackageUtils;
  4. import com.ajunframework.beans.utils.PubConstant;
  5. /**
  6.  * 获得某个包或者子包下的所有class
  7.  * @author ajun
  8.  * @http://blog.csdn.net/ajun_studio
  9. */
  10. public class ScanClass {
  11.     /**
  12.      * 获得某个包或者子包下的所有class
  13.      * @return
  14.      */
  15.     public static Class<?>[] getScanPackageClasses(){
  16.         String packageLink = PubConstant.getValue("scan-package");
  17.         Class<?>[] clas=null;
  18.         try {
  19.             clas = PackageUtils.getClasses(packageLink);
  20.         } catch (ClassNotFoundException e) {
  21.             e.printStackTrace();
  22.         } catch (IOException e) {
  23.             e.printStackTrace();
  24.         }
  25.         return clas;
  26.     }
  27. }
到目前为止,可以扫描指定package以及子package下的所有class了,下一节我们会介绍怎么收集和整理这些扫描到得class的信息
正文到此结束
Loading...