<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="personDao" class="junit.test12.PersonDaoBean"/> <bean id="personService" class="junit.test12.PersonServiceBean"> <property name="id" value="24"/> <property name="name" value="zyj"/> <!-- <property name="personDao" ref="personDao"/> --> </bean> </beans>
package junit.test12;
import java.util.ArrayList;
import java.util.List;
/**
* xml中的<bean/>的定义
* @author Administrator
*
*/
public class BeanDefinition {
private String id;
private String clazz;
private List<PropertyDefinition> propertyDefinitions=new ArrayList<PropertyDefinition>();
public BeanDefinition(String id, String clazz) {
super();
this.id = id;
this.clazz = clazz;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
public List<PropertyDefinition> getPropertyDefinitions() {
return propertyDefinitions;
}
public void setPropertyDefinitions(List<PropertyDefinition> propertyDefinitions) {
this.propertyDefinitions = propertyDefinitions;
}
}
package junit.test12;
public class PropertyDefinition {
private String name;
private String ref;
private String value;
public PropertyDefinition(String name, String ref,String value) {
super();
this.name = name;
this.ref = ref;
this.value=value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package junit.test12;
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 UserDefinedResource {
public String name() default "";
}
//使用dom4j读取spring配置文件
package junit.test12;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
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 junit.test12.BeanDefinition;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
/**
* 自定义容器
* @author Administrator
*
*/
public class UserDefinedClassPathXMLApplicationContext {
private List<BeanDefinition> beanDefinitions=new ArrayList<BeanDefinition>();
private Map<String, Object> sigletons=new HashMap<String, Object>();
public UserDefinedClassPathXMLApplicationContext(String filename){
this.readXML(filename);
this.instanceBeans();
this.annotationInject();
this.injectObject();
}
/**
* 读取xml配置文件
* @param filename
*/
private void readXML(String filename){
SAXReader saxReader=new SAXReader();
Document document=null;
try {
URL xmlPath=this.getClass().getClassLoader().getResource(filename);
document=saxReader.read(xmlPath);
XPath xPath=document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径。从根路径开始
Map<String, String> nsMap=new HashMap<String, String>();
nsMap.put("ns", "http://www.springframework.org/schema/beans");//加入命名空间
xPath.setNamespaceURIs(nsMap);//设置命名空间
List<Element> beans=xPath.selectNodes(document);//获取文档下所有bean节点
for (Element element : beans) {
String id=element.attributeValue("id");
String clazz=element.attributeValue("class");
BeanDefinition beanDefinition=new BeanDefinition(id, clazz);
XPath xPath2=element.createXPath("ns:property");//从相对路径开始
xPath2.setNamespaceURIs(nsMap);
List<Element> propertys=xPath2.selectNodes(element);
for (Element element2 : propertys) {
String name=element2.attributeValue("name");
String ref=element2.attributeValue("ref");
String value=element2.attributeValue("value");
PropertyDefinition propertyDefinition=new PropertyDefinition(name, ref,value);
beanDefinition.getPropertyDefinitions().add(propertyDefinition);
}
beanDefinitions.add(beanDefinition);
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 完成bean的实例化
*/
private void instanceBeans(){
try {
for (BeanDefinition beanDefinition : beanDefinitions) {
if (beanDefinition.getClazz()!=null&&!"".equals(beanDefinition.getClazz().trim())) {
sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClazz()).newInstance());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 为bean对象的属性注入值
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void injectObject() {
try {
for (BeanDefinition beanDefinition : beanDefinitions) {
Object bean=sigletons.get(beanDefinition.getId());
if (bean!=null) {
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDefinition propertyDefinition:beanDefinition.getPropertyDefinitions()){
for (PropertyDescriptor propertyDescriptor : ps) {
if (propertyDefinition.getName().equals(propertyDescriptor.getName())) {
Method setterMethod=propertyDescriptor.getWriteMethod();//获取属性的setter方法
if (setterMethod!=null) {
Object temp=null;
if (propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())) {
temp=sigletons.get(propertyDefinition.getRef());
}else if (propertyDefinition.getValue()!=null&&!"".equals(propertyDefinition.getValue().trim())) {
temp=ConvertUtils.convert(propertyDefinition.getValue(), propertyDescriptor.getPropertyType());
}
setterMethod.setAccessible(true);//防止setter方法为private
setterMethod.invoke(bean, temp);//把引用对象注入到属性
}
break;
}
}
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 通过注解实现注入依赖对象
* @throws IntrospectionException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
private void annotationInject(){
try {
for (String beanName : sigletons.keySet()) {
Object bean=sigletons.get(beanName);
if (bean!=null) {
PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : ps) {
Method setterMethod=propertyDescriptor.getWriteMethod();
if (setterMethod!=null&&setterMethod.isAnnotationPresent(UserDefinedResource.class)) {
UserDefinedResource userDefinedResource=setterMethod.getAnnotation(UserDefinedResource.class);
Object temp = null;
if(userDefinedResource.name()!=null && !"".equals(userDefinedResource.name())){
//一旦指定了name属性,就只能按名称装配了
temp = sigletons.get(userDefinedResource.name());
}else{
temp = sigletons.get(propertyDescriptor.getName());
if(temp==null){
for(String key : sigletons.keySet()){
if(propertyDescriptor.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){
temp = sigletons.get(key);
break;
}
}
}
}
setterMethod.setAccessible(true);
setterMethod.invoke(bean, temp);//把引用对象注入到属性
}
}
Field[] fields = bean.getClass().getDeclaredFields();
for(Field field : fields){
if(field.isAnnotationPresent(UserDefinedResource.class)){
UserDefinedResource userDefinedResource = field.getAnnotation(UserDefinedResource.class);
Object temp = null;
if(userDefinedResource.name()!=null && !"".equals(userDefinedResource.name())){
temp = sigletons.get(userDefinedResource.name());
}else{
temp = sigletons.get(field.getName());
if(temp==null){
for(String key : sigletons.keySet()){
if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){
temp = sigletons.get(key);
break;
}
}
}
}
field.setAccessible(true);//允许访问private字段
field.set(bean, temp);
}
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 获取bean实例
* @param beanName
* @return
*/
public Object getBean(String beanName){
return this.sigletons.get(beanName);
}
}
package junit.test12;
import static org.junit.Assert.*;
import junit.test12.PersonService;
import junit.test12.UserDefinedClassPathXMLApplicationContext;
import org.junit.Test;
public class SpringTest {
@Test
public void instanceSpring() {
UserDefinedClassPathXMLApplicationContext applicationContext=new UserDefinedClassPathXMLApplicationContext("beans.xml");
PersonService personService=(PersonService) applicationContext.getBean("personService");
personService.save();
}
}