自己动手实现IOC和MVC(二)

本文介绍了如何通过定义自定义注解并使用实用工具类扫描指定包及其子包下的所有类来构建简易的IoC框架。重点讲解了创建用于标记DAO、Service、Action层的Bean以及依赖注入的Java注解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


上一节介绍了一些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

   java annotation Dao.java

package com.ajunframework.beans.annotation;
import java.lang.annotation.Documented;
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;

/**
 * 应用于dao层实例化
 * @author ajun
 * @http://blog.youkuaiyun.com/ajun_studio
 */
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Inherited  
public @interface Dao {

	public String value() default "";
	
}

   java annotation Service.java

package com.ajunframework.beans.annotation;
import java.lang.annotation.Documented;
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;

import com.ajunframework.beans.constant.BeanScop;

/**
 * 实例化service
 * @author ajun
 * @http://blog.youkuaiyun.com/ajun_studio
 */
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Inherited  
public @interface Service {

	public String value() default “”;
	
}

  java annotation Action.java

package com.ajunframework.beans.annotation;
import java.lang.annotation.Documented;
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;

/**
 * 应用在action 实例化
 * @author ajun
 * @http://blog.youkuaiyun.com/ajun_studio
 */
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Inherited  
public @interface Action {

	public String value() default "";
	
}

      java annotation Property.java

package com.ajunframework.beans.annotation;

import java.lang.annotation.Documented;
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;

/**
 * 进行依赖注入
 * @author ajun
 * @http://blog.youkuaiyun.com/ajun_studio
 */
@Target(ElementType.FIELD) 
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Inherited  
public @interface Property {

    public String value() default "";
}

 ②怎么扫描?

这里提供一个用于扫描package以及package子包下的所有class PackageUtils.java

package com.ajunframework.beans.utils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

/**
 * @author ajun
 * @http://blog.youkuaiyun.com/ajun_studio
 */
public class PackageUtils {

	/**
	 * 扫描给定包及子包内的所有类
	 * 
	 * @param packageName
	 *            给定的包名
	 * @return The classes
	 * @throws ClassNotFoundException
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public static Class[] getClasses(String packageName)
			throws ClassNotFoundException, IOException {
		Class cla = PackageUtils.class;
		String path = packageName.replace('.', '/');
		Enumeration<URL> resources = cla.getClassLoader().getResources(path);
		List<File> dirs = new ArrayList<File>();

		while (resources.hasMoreElements()) {
			URL resource = resources.nextElement();
			dirs.add(new File(resource.getFile()));
		}
		ArrayList<Class> classes = new ArrayList<Class>();
		for (File directory : dirs) {
			classes.addAll(findClasses(directory, packageName));
		}
		return classes.toArray(new Class[classes.size()]);
	}

	/**
	 * 找到制定包内的所有class文件
	 * 
	 * @param directory
	 *            目录名称
	 * @param packageName
	 *            包名称
	 * @return The classes
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("unchecked")
	private static List<Class> findClasses(File directory, String packageName)
			throws ClassNotFoundException {
		List<Class> classes = new ArrayList<Class>();
		if (!directory.exists()) {
			return classes;
		}
		File[] files = directory.listFiles();
		for (File file : files) {
			if (file.isDirectory()) {
				classes.addAll(findClasses(file,
						packageName + "." + file.getName()));
			} else if (file.getName().endsWith(".class")) {
				classes.add(Class.forName(packageName
						+ '.'
						+ file.getName().substring(0,
								file.getName().length() - 6)));
			}
		}
		return classes;
	}

	/**
	 * @throws IOException
	 * @throws ClassNotFoundException
	 * 
	 */
//	public static void main(String[] args) throws Exception {
//		Class[] clas = PackageUtils.getClassess("com.ajunframework.utils");
//		for (Class cla : clas) {
//			System.out.println(cla.getName());
//		}
//	}

}


  扫描的路径怎么传入呢 ?这里可以定义一个properties文件 用于定义一些常量

constant.properties

scan-package=com.ajun.test #这里是你要的package的路径

下面可以提供一个读取constant.properties文件 ,供外包调用返回class[]数组的工具类 ScanClass.java

package com.ajunframework.beans.scan;

import java.io.IOException;

import com.ajunframework.beans.utils.PackageUtils;
import com.ajunframework.beans.utils.PubConstant;

/**
 * 获得某个包或者子包下的所有class
 * @author ajun
 * @http://blog.youkuaiyun.com/ajun_studio
*/
public class ScanClass {

	/**
	 * 获得某个包或者子包下的所有class
	 * @return
	 */
	public static Class<?>[] getScanPackageClasses(){
		String packageLink = PubConstant.getValue("scan-package");
		Class<?>[] clas=null;
		try {
			clas = PackageUtils.getClasses(packageLink);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return clas;
	}
}

到目前为止,可以扫描指定package以及子package下的所有class了,下一节我们会介绍怎么收集和整理这些扫描到得class的信息



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Shark

感谢打赏,thanks

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值