Spring 之 编码实现 @Resource注解属性注入

下边只给出 key code:

package com.ethan.annotation;

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

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface EthanResource {
	public String name() default "";
}

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.apache.commons.beanutils.ConvertUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

import com.ethan.annotation.EthanResource;


public class EthanClassPathXMLApplicationContext {
	private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
	private Map<String,Object> singletons = new HashMap<String, Object>();
	
	public EthanClassPathXMLApplicationContext(String filename) throws Exception {
		this.readXML(filename);
		this.instanceBeans();
		this.annotationInject();
		this.injectObject();
	}
	
	private void annotationInject() {
		//给所有beans注入property
		for(String beanName:singletons.keySet()) {
			Object bean = singletons.get(beanName);
			
			if(bean!=null) {
				try {
					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					for(PropertyDescriptor properdesc:ps) {
						Method setter = properdesc.getWriteMethod();
						//方法上有注解
						if(setter!=null&&setter.isAnnotationPresent(EthanResource.class)) {
							//取得注解
							EthanResource resource = setter.getAnnotation(EthanResource.class);
							Object value = null;
							//判断name属性
							if(resource.name()!=null&&!"".equals(resource.name())) {
								//属性bean name
								String name = resource.name();
								value = singletons.get(name);
								
								
							} else {
								//注解name="" 默认去属性名,如果value==null 则去按类型
								value = singletons.get(properdesc.getName());
								if(value==null) {
									//那么按照类型去找,遍历beans 判断类型
									for(String key:singletons.keySet()) {
										//判断类型 是否同一类型
										if(properdesc.getPropertyType().isAssignableFrom(singletons.get(key).getClass())) {
											value = singletons.get(key);
											break;
										}
									}
								}
								
							}
							
							setter.setAccessible(true);
							setter.invoke(bean, value);
						}
					}
					
					//如果注解在field
					
					Field[] fields = bean.getClass().getDeclaredFields();
					for(Field field:fields) {
						if(field.isAnnotationPresent(EthanResource.class)) {
							//取得注解
							EthanResource resource = field.getAnnotation(EthanResource.class);
							//要注入的属性变量值
							Object value = null;
							
							if(resource.name()!=null&&!"".equals(resource.name())) {
								//如果注解(name="xxx")直接去map拿
								value = singletons.get(resource.name());
							} else {
								//根据属性名字来拿
								value = singletons.get(field.getName());
								if(value!=null) {
									
									//遍历所有的beans
									for(String key:singletons.keySet()) {
										//按照类型 去 注入
										if(field.getType().isAssignableFrom(singletons.get(key).getClass())) {
											value = singletons.get(key);
											break;
										}
									}
								}
							}
							
							field.setAccessible(true);
							field.set(bean, value);
						}
					}
				} catch(Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void injectObject() {
		for(BeanDefinition beanDefinition:beanDefines) {
			Object bean = singletons.get(beanDefinition.getId());
			if(bean!=null) {
				//获得此对象的所有属性
				try {
					
					//这个对象的所有成员变量属性
					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					//标签注入的属性<property>
					for(PropertyDefinition propertyDefinition:beanDefinition.getPropertys()) {
						for(PropertyDescriptor properdesc:ps) {
							if(propertyDefinition.getName().equals(properdesc.getName())) {
								Method setter = properdesc.getWriteMethod();
								if(setter!=null) {
									Object propervalue = null;
									if(propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())) {
										propervalue = singletons.get(propertyDefinition.getRef()); 
										
									} else {
										//基本类型属性
										
										propervalue = ConvertUtils.convert(propertyDefinition.getValue(),properdesc.getPropertyType() );
										System.out.println("id--------"+propervalue);
									}
									setter.setAccessible(true);
									setter.invoke(bean, propervalue);
								}
								break;
							}
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		}
	}

	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");
			//创建beans/bean 查询路径  /根节点<beans> /+/beans+/+bean
			XPath xsub = document.createXPath("//ns:beans/ns:bean");
			
			xsub.setNamespaceURIs(nsMap);
			
			//拿到docuemnt内的所有bean元素
			List<Element> beans = xsub.selectNodes(document);
			
			for(Element element:beans) {
				String id = element.attributeValue("id");
				String clazz = element.attributeValue("class");
				
				BeanDefinition beanDefine = new BeanDefinition(id, clazz);
				
				XPath propertysub = element.createXPath("ns:property");
				propertysub.setNamespaceURIs(nsMap);
				//这个<bean>下的所有<property>
				List<Element> propertys = propertysub.selectNodes(element);
				
				for(Element property:propertys) {
					String propertyName = property.attributeValue("name");
					String propertyref = property.attributeValue("ref");
					//基本属性值
					String properValue = property.attributeValue("value");
					PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref,properValue);
					
					beanDefine.getPropertys().add(propertyDefinition);
				}
				
				beanDefines.add(beanDefine);
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	private void instanceBeans() throws Exception {
		for(BeanDefinition beanDefinition:beanDefines) {
			if(beanDefinition.getClassName()!=null&&!"".equals(beanDefinition.getClassName().trim())) {
				singletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
				
			}
		}
	}
	
	public Object getBean(String beanName) {
		return this.singletons.get(beanName);
	}
}

<bean id="personDao" class="com.ethan.dao.impl.PersonDaoBean"/>
	<bean id="personService" class="com.ethan.service.impl.PersonServiceBean" init-method="init" destroy-method="close">
		<!-- <property name="personDao" ref="personDao"/>
		<property name="id" value="88"/> -->
	</bean>

public static void test5() throws Exception {
		EthanClassPathXMLApplicationContext ctx = new EthanClassPathXMLApplicationContext("beans.xml");
		PersonService ps = (PersonService) ctx.getBean("personService");
		ps.save();
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值