jdk模拟 spring 利用注解完成依赖注入功能

     依赖注入是Spring中一个极其重要的概念。    

     本文通过JDK的注解和反射机制来完成在Spring中完成依赖注入的功能。

 

     预备知识,注解,反射机制

     完成一个注解我们通常需要三个步骤1,定义注解,2,使用注解,3,解析注解

     下面我们通过实例来解释注解的使用

     定义注解

package cn.tang.demos.spring;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD) //注解用在什么地方,method,field,class,type
@Retention(RetentionPolicy.RUNTIME)//注解用在什么级别,Source,class,runtime
public @interface Autoware {
	String description() default "类似spring的自动装载";//注解元素的默认值
}

 使用注解

package cn.tang.demos.spring;

public class Bean {
	@Autoware(description="数据访问接口")
	private MysqlDao dao;
	
	public void testAdd(){
		dao.add();
	}

	public MysqlDao getDao() {
		return dao;
	}

	public void setDao(MysqlDao dao) {
		this.dao = dao;
	}

}

 解析注解,下面代码包括了依赖注入的内容

package cn.tang.demos.spring;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class DITest {
	/**
	 * 依赖注入的测试类,假设已经从xml配置文件中读取出来了两个Bean的类名
	 */
	private static final String daoClassStr = "cn.tang.demos.spring.MysqlDao";
	private static final String beanClassStr = "cn.tang.demos.spring.Bean";

	public static void main(String[] args) {
		try {
			test();// 为了能让代码更加直观,没有分别处理所有类型的异常,也没有多余的判断
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@SuppressWarnings("unchecked")
	public static void test() throws Exception {
		// 根据类名得到类类型
		Class daoClass = Class.forName(daoClassStr);
		// 根据类得到该类的构造方法
		Constructor daoCon = daoClass.getDeclaredConstructors()[0];
		// 调用构造方法得到类的一个实例
		MysqlDao dao = (MysqlDao) daoCon.newInstance();

		// 根据类名得到类类型
		Class beanClass = Class.forName(beanClassStr);
		// 根据类得到该类的构造方法
		Constructor beanCon = beanClass.getDeclaredConstructors()[0];
		// 调用构造方法得到类的一个实例
		Object beanObject = beanCon.newInstance();
		// 遍历所有的属性
		for (Field f : beanClass.getDeclaredFields()) {
			// 获取有注入类型的注解
			Autoware an = (Autoware) f.getAnnotation(Autoware.class);
			// 根据属性得到声明属性的类型 f.getGenericType()
			if (an != null) {
				// 输出注解的描述内容
				System.out.println("annotation description : "
						+ an.description());
				// 得到与该属性的set方法,这也是为什么spring中的属性需要set方法
				String setMethodName = "set"
						+ f.getName().substring(0, 1).toUpperCase()
						+ f.getName().substring(1);
				//得到该方法
				Method m = beanClass.getDeclaredMethod(setMethodName,
						new Class[] { (Class) f.getGenericType() });
				if (m != null) {
					//反射机制调用该方法,注入DAO到bean中
					m.invoke(beanObject, dao);
				}
			}
		}
		
		//现在我们得到了一个注入了dao的bean了,我们调用bean中的方法
		((Bean) beanObject).testAdd();
	}

}
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值