使用JAVA注解和反射模拟spring的IOC

自定义注解
package com.imooc.annotation.spring.annotation;

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

@Target(value=ElementType.METHOD)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Bean {
	
	public String value();
	
	

}


package com.imooc.annotation.spring.annotation;

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

@Target(value=ElementType.TYPE)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Configuration {

}



package com.imooc.annotation.spring.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 用在字段上,表示引用的Bean
 */
@Target(value=ElementType.FIELD)
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Resource {
	
	String value();

	
}


业务代码类:

public class BookHotelImpl implements IBook {

	public void book() {
		System.out.println("go hotel");
	}

}

public class BookRestaurantImpl implements IBook {

	public void book() {
		System.out.println("go restaurant...");
	}

}

public interface IBook {
	
	public void book();

}


package com.imooc.annotation.spring;

import com.imooc.annotation.spring.annotation.Bean;
import com.imooc.annotation.spring.annotation.Configuration;
import com.imooc.annotation.spring.impl.BookHotelImpl;
import com.imooc.annotation.spring.impl.BookRestaurantImpl;
import com.imooc.annotation.spring.impl.IBook;

@Configuration
public class BeansXML {
	
	@Bean(value="bookHotel")
	public IBook bookHotel() {
		return new BookHotelImpl();
	}
	
	@Bean(value="bookRestaurant")
	public IBook bookRestaurant() {
		return new BookRestaurantImpl();
	}
	
	@Bean(value="holiday")
	public Holiday funnyHoliday() {
		return new Holiday();
	}

}


package com.imooc.annotation.spring;

import com.imooc.annotation.spring.annotation.Resource;
import com.imooc.annotation.spring.impl.IBook;

public class Holiday {
	
	@Resource(value="bookRestaurant")
	private IBook book;
	
	public void setBook(IBook book) {
		this.book = book;
	}
	
	public void haveFun() {
		book.book();
	}
	

}



工具类:

package com.imooc.annotation.spring;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.imooc.annotation.spring.annotation.Bean;
import com.imooc.annotation.spring.annotation.Configuration;
import com.imooc.annotation.spring.annotation.Resource;

public class ApplicationContext {
	
	private Class<?> configClass;
	
	private Map<String,Method> mapMethods;
	
	//构造函数,
	public ApplicationContext(Class<?> conClass) {
		this.configClass = conClass;
		if(checkConfigClass()) {
			mapMethods = getDeclaredMethods(configClass);
		}
	}

	//判断配置文件是否使用@Configuration注解
	private boolean checkConfigClass() {
		boolean useConfiguration = false;
		useConfiguration = configClass.isAnnotationPresent(Configuration.class);
		if(!useConfiguration) {
			System.out.println("配置文件类 :" + configClass.getName() + "缺少@Configuration注解");
		}
		return useConfiguration;
	}
	
	//获取一个类中所有使用@Bean注解的方法
	private Map<String,Method> getDeclaredMethods(Class<?> clazz) {
		Map<String,Method> resultMap = new HashMap<String, Method>();
		try {
			for(Method m : clazz.getDeclaredMethods()) {
				//获取每个方法的@bean注解
				Bean beanMethod = m.getAnnotation(Bean.class);
				if(null != beanMethod) {
					String annoName = beanMethod.value();
					//@Bean如果没有自定义value,使用方法名作为value
					annoName = ("".equals(annoName)) ? m.getName() : annoName;
					resultMap.put(annoName,m);
				}
			}
		} catch (SecurityException e) {
			System.out.println("读取配置文件错误" + e);
		}
		
		return resultMap;
	}
	
	//获取类实例
	private <T> T getInstance(Class<T> clazz) {
		T instance = null;
		try {
			instance = clazz.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return instance;
	}
	
	
	//根据bean名称获取bean
	public  <T> T getBean(String beanName) {
		//Bean实例
		T instance = null;
		
		//配置文件类的实例
		Object configObj = getInstance(configClass);
		
		//遍历所有定义的Bean
		Set<String> annoNames = mapMethods.keySet();
		
		for(String annoName : annoNames) {
			Method m = mapMethods.get(annoName);
			
			if(beanName.equals(annoName)) {
				try {
					instance = (T) m.invoke(configObj);
					
					//实例对象对应的Class类型
					Class<?> instanceClass = instance.getClass();
					
					for(Field field : instanceClass.getDeclaredFields()) {
						//读取属性上的@Resouce注解信息
						Resource res = field.getAnnotation(Resource.class);
						
						if(null != res) {
							//获取注解值
							String resValue = res.value();
							
							//判断是否已在配置文件类中已注册
							Method refM = mapMethods.get(resValue);
							if(null != refM) {
								//获取属性对应的标准setter方法名称
								String setterName = "set" + field.getName().substring(0, 1).toUpperCase() 
										+ field.getName().substring(1);
								Method setter = instanceClass.getMethod(setterName,field.getType());
								
								//执行setter方法
								setter.invoke(instance,refM.invoke(configObj));
							}
							
						}
					}
					
					
				} catch (Exception e) {
					e.printStackTrace();
				} 
			}
		}
		
		return instance;
		
	}
	
	
}


测试类:

package com.imooc.annotation.spring;

public class Test {
	
	public static void main(String[] args) {
		//加载配置文件并获取上下文
		ApplicationContext ctx = new ApplicationContext(BeansXML.class);
		
		Holiday holiday = ctx.getBean("holiday");
		holiday.haveFun();
	}

}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值