zoukankan      html  css  js  c++  java
  • 编码实现Spring 利用@Resource注解实现bean的注入,xml实现基本数据类型的注入

    首先分析。

    1: 肯定要利用dom4j读取xml配置文件,将所有的bean的配置信息读取出来

    2: 利用反射技术,实例化所有的bean

    3: 写注解处理器, 利用注解和内省实现依赖对象的注入。

    4: 利用XML中<property>信息,通过内省beanUtils实现基本数据类型的注入

    实现:

    package cn.gbx.example;
    
    
    import java.beans.IntrospectionException;
    import java.beans.Introspector;
    import java.beans.PropertyDescriptor;
    import java.io.File;
    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;
    public class MyClassPathXmlApplicationContext {
    	private List<DefBean> defBeans = new ArrayList<DefBean>();
    	private Map<String, Object> singletons = new HashMap<String, Object>();
    	
    	public MyClassPathXmlApplicationContext(String filename) {
    		this.readXML(filename);
    		this.instanceBean();
    		this.injectAnotation();
    		this.injectXML();
    		
    	}
    
    	//注入基本类型的属性
    	private void injectXML() {
    		//枚举bean
    		for (DefBean defBean : defBeans) {
    			Object bean = singletons.get(defBean.getId());
    			if (bean != null) {
    				//枚举该bean的Property看有没有基本数据类型的注入
    				for (DefProperty defProperty : defBean.getDefPropertys()) {
    					if (defProperty.getValue() != null){
    						try {
    							PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
    							for (PropertyDescriptor p : ps) {
    								if (p.getName().equals(defProperty.getName())) {
    									Method setter = p.getWriteMethod();
    									//保证有set方法
    									if (setter != null) {
    										Object value = ConvertUtils.convert(defProperty.getValue(), p.getPropertyType());
    										setter.setAccessible(true);
    										setter.invoke(bean, value);
    									}
    									break;
    								}
    							}
    						} catch (Exception e) {
    							// TODO Auto-generated catch block
    							e.printStackTrace();
    						}
    					}
    				}
    			}
    		}
    	}
    
    	//注解处理器
    	private void injectAnotation() {
    		//枚举实例化的bean
    		for (String key : singletons.keySet()) {
    			Object bean = singletons.get(key);
    			if (bean != null) {
    				
    				/*
    				 * 检查setter方法
    				 */
    				try {
    					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
    					//枚举每个bean的属性
    					for (PropertyDescriptor p : ps) {
    						Method setter = p.getWriteMethod();
    						Object value = null;
    						//存在set方法, 并且有setter上边有Resource注解
    						if (setter != null && setter.isAnnotationPresent(GbxResource.class)){
    							GbxResource gbxResource = setter.getAnnotation(GbxResource.class);
    							//若有name 则按name查找
    							if (gbxResource.name() != null && !"".equals(gbxResource.name())) {
    								value = singletons.get(gbxResource.name());
    							} else { //若没有,先安名字查找, 再按数据类型查找
    								value = singletons.get(p.getName());
    								if (value == null) {
    									for (String key2 : this.singletons.keySet()) {
    										if (p.getPropertyType().isAssignableFrom(this.singletons.get(key2).getClass())) {
    											value = this.singletons.get(key2);
    											break;
    										}
    									}
    								}
    							}
    							setter.setAccessible(true);
    							setter.invoke(bean, value);
    						}
    					}
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				
    				/*
    				 * 检查字段
    				 */
    				 Field[] fileds = bean.getClass().getDeclaredFields();
    				 for (Field field : fileds) {
    					 if (field.isAnnotationPresent(GbxResource.class)) {
    						 GbxResource gbxResource = field.getAnnotation(GbxResource.class);
    						 Object value = null;
    						 if (gbxResource.name() != null && !"".equals(gbxResource.name())) {
    							 value = this.singletons.get(gbxResource.name());
    						 } else {
    							 value = this.singletons.get(field.getName());
    							 if (value == null) {
    								for (String key2 : this.singletons.keySet()) {
    									if (field.getType().isAssignableFrom(this.singletons.get(key2).getClass())) {
    										value = this.singletons.get(key2);
    										break;
    									}
    								}
    							 }
    						 }
    						 field.setAccessible(true);
    						 try {
    							field.set(bean, value);
    						} catch (IllegalAccessException e) {
    							e.printStackTrace();
    						}
    					 }
    				 }
    			}
    		}
    		
    	}
    
    	//实例化bean对象
    	private void instanceBean() {
    		for (DefBean bean : defBeans) {
    			System.out.println(bean.getId() + " : " + bean.getClassName());
    			if (bean.getClassName() != null && !"".equals(bean.getClassName())) {
    				try {
    					singletons.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    	//读取xml文件
    	private void readXML(String filename) {
    		SAXReader reader = new SAXReader();
    		Document document = null;
    		URL xmlPath = this.getClass().getClassLoader().getResource(filename);
    		
    		try {
    			//的到document
    			document = reader.read(xmlPath);
    			//设置命名空间
    			Map<String, String> nsMap = new HashMap<String, String>();
    			nsMap.put("ns", "http://www.springframework.org/schema/beans");
    			//创建查询路径
    			XPath xPath = document.createXPath("//ns:beans/ns:bean");
    			xPath.setNamespaceURIs(nsMap);
    			
    			List<Element> beans = xPath.selectNodes(document);
    			DefBean defBean = null;
    			for (Element e : beans) {
    				String id = e.attributeValue("id");
    				String className = e.attributeValue("class");
    				defBean = new DefBean(id, className);
    				
    				XPath xPath2 = e.createXPath("ns:property");
    				xPath2.setNamespaceURIs(nsMap);
    				List<Element> propertys = xPath2.selectNodes(e);
    				
    				DefProperty defProperty = null;
    				for (Element e2 : propertys) {
    					String name = e2.attributeValue("name");
    					String ref = e2.attributeValue("ref");
    					String value = e2.attributeValue("value");
    					
    					defProperty = new DefProperty(name, ref, value);
    					defBean.getDefPropertys().add(defProperty);
    				}
    				defBeans.add(defBean);
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	public Object getBean(String key) {
    		return singletons.get(key);
    	}
    }
    

      

    package cn.gbx.serviceimpl;
    
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    import javax.annotation.Resource;
    
    import org.springframework.beans.factory.annotation.Autowired;
    
    import cn.gbx.daoimpl.PersonDao;
    import cn.gbx.example.GbxResource;
    import cn.gbx.service.PersonService;
    
    public class PersonServiceImpl implements PersonService {
    	@GbxResource
    	private PersonDao personDao;
    	private String name;
    	
    	
    
    	public void save() {
    		personDao.save();
    		System.out.println("Name = " + name);
    		System.out.println("service层的 save方法");
    	}
    
    	public void setPersonDao(PersonDao personDao) {
    		this.personDao = personDao;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public PersonDao getPersonDao() {
    		return personDao;
    	}
    	
    	
    	
    }
    

      

    注解:

    package cn.gbx.example;
    
    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.METHOD, ElementType.FIELD})
    public @interface GbxResource {
    	public String name() default "";
    }
    

      

  • 相关阅读:
    springboot mybatis使注解和xml两种方式同时生效
    maven setting 配置仓库,pom.xml中repository不起作用
    k8s ocker-engine-selinux conflicts with 2:container-selinux-2.107-1.el7_6.noarch
    linux ,查看端口
    java,string和list,list和set相互转换
    sprintboot+mybatis+@Mapper中in的使用方法
    自动添加芝麻代理白名单的方法
    python 本地时间+8小时
    Android Studio镜像设置
    AndroidStudio初次使用
  • 原文地址:https://www.cnblogs.com/E-star/p/3560070.html
Copyright © 2011-2022 走看看