模拟Spring控制反转、依赖注入(包注解)

package com.spring.test;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;


public class MySpring {

List<BeanDefinition> beanDefines=new ArrayList<BeanDefinition>();
Map<String, Object> map=new HashMap<String, Object>();

public MySpring(String filename){
//读取XML文件,遍历bean,存放到List
readXML(filename);
//遍历bean集合,利用反射实例化bean,存放到Map
instanceBean();
//依赖注入
injectObject();
//注解注入
annotationInject();
}

private void annotationInject() {
for(String name : map.keySet()){
Object bean=map.get(name);
if(bean!=null){
try {
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDescriptor propertyDescriptor : ps){
Method setter=propertyDescriptor.getWriteMethod();//获取setter方法

//判断注解是否存在
if(setter!=null && setter.isAnnotationPresent(MyResource.class)){
MyResource myResource=setter.getAnnotation(MyResource.class);
Object value=null;
//声明name属性
if(myResource.name()!=null && !"".equals(myResource.name())){
value=map.get(myResource.name());
}else{
value=map.get(propertyDescriptor.getName());
if(value==null){
for(String key : map.keySet()){
if(propertyDescriptor.getPropertyType().isAssignableFrom(map.get(key).getClass())){
value=map.get(key);
break;
}
}
}
}
setter.setAccessible(true);
setter.invoke(bean, value);//把引用对象注入到属性中
}
}
//字段
Field[] fields=bean.getClass().getFields();
for(Field field : fields){
if(field.isAnnotationPresent(MyResource.class)){
MyResource myResource=field.getAnnotation(MyResource.class);
Object value=null;
//声明name属性
if(myResource.name()!=null && !"".equals(myResource.name())){
value=map.get(myResource.name());
}else{
value=map.get(field.getName());
if(value==null){
for(String key : map.keySet()){
if(field.getType().isAssignableFrom(map.get(key).getClass())){
value=map.get(key);
break;
}
}
}
}
field.setAccessible(true);
field.set(bean,value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

private void injectObject() {
//循环所有的bean节点
for(BeanDefinition beanDefinition : beanDefines){
Object bean= map.get(beanDefinition.getId());
if(bean!=null){

try {
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
//循环所有的property节点
for(PropertyDefinition propertyDefinition : beanDefinition.getProperties()){
for(PropertyDescriptor propertyDescriptor : ps){
if(propertyDefinition.getName().equals(propertyDescriptor.getName())){
Method setter=propertyDescriptor.getWriteMethod();//获取setter方法
if(setter!=null){
Object value=map.get(propertyDefinition.getRef());
//如果private,设置允许访问
setter.setAccessible(true);
setter.invoke(bean, value);//把引用对象注入到属性中
}
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

@SuppressWarnings("unchecked")
private void readXML(String filename) {
SAXReader saxReader = new SAXReader();
Document document=null;
try{
URL xmlpath = this.getClass().getClassLoader().getResource(filename);
document = saxReader.read(xmlpath);
Map<String,String> nsMap = new HashMap<String,String>();
nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间
XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
xsub.setNamespaceURIs(nsMap);//设置命名空间
List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点

for(Element element : beans){
String id = element.attributeValue("id");//获取id属性值
String clazz = element.attributeValue("class"); //获取class属性值
BeanDefinition beanDefine = new BeanDefinition(id, clazz);

XPath propertysub = element.createXPath("ns:property");//创建beans/property查询路径
propertysub.setNamespaceURIs(nsMap);//设置命名空间
List<Element> propertys = propertysub.selectNodes(element);//获取文档下所有property节点
for(Element property : propertys){
String propertyName=property.attributeValue("name");
String propertyRef=property.attributeValue("ref");
System.out.println(propertyName+propertyRef);
PropertyDefinition pd=new PropertyDefinition(propertyName,propertyRef);
beanDefine.getProperties().add(pd);
}

beanDefines.add(beanDefine);
}
}catch(Exception e){
e.printStackTrace();
}
}

private void instanceBean() {
for(BeanDefinition bean : beanDefines){
try {
if(bean.getClassName()!=null && !"".equals(bean.getClassName()))
//实例化Bean对象
map.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}

public Object getBean(String id){
return this.map.get(id);
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值