package org.cgz.test; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; 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<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>(); private Map<String, Object> intsances = new HashMap<String, Object>(); /** * 容器初始化时 传入配置文件名称 读取配置文件..实例化bean * @param configFileName */ public MyClassPathXmlApplicationContext(String configFileName) { readConfig(configFileName); instanceBeans(); annotationInject(); Injected(); } /** * 注解实现依赖注入 */ private void annotationInject() { /** * 遍历bean,获取bean里的所有属性描述对象,遍历属性描述对象数组. * ---获取属性的setter方法.如果该属性setter方法存在,判断方法上是否有MyResource注解, * 如果有,获取注解对象,通过注解对象获取name值 * 如果name值存在:根据name值查找Map中是否有该名称的bean,如果有,调用该属性的setter方法执行注入. * 如果name值不存在:获取该属性的名称,从map中查找是否有此名称的bean. * 如果有:调用setter方法注入 * 没有:获取该属性的类型,遍历map查找map中是否有和此属性类型一致的bean,如果有,则执行注入 * *---获取该属性,判断该属性上是否有MyResource注解 * 如果有:获取该注解的对象,通过该对象获取name值 * 如果name值存在:根据name值查找map中是否有该bean如果有则执行注入 * 如果name值不存在:获取该属性的名称,查找map中是否有该名称的bean * 如果有:执行注入 * 没有:获取该属性的类型 遍历map中判断是否有和该类型一致的bean * */ for(String beanName : intsances.keySet()) { Object bean = intsances.get(beanName); if(bean != null) { try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDescriptor propertyDesc : ps) { Method setter = propertyDesc.getWriteMethod(); if(setter != null && setter.isAnnotationPresent(MyResource.class)) { MyResource myResource = setter.getAnnotation(MyResource.class); Object value = null; if(myResource.name() != null && !"".equals(myResource.name())) { value = intsances.get(myResource.name()); }else { value = intsances.get(propertyDesc.getName()); if(value == null) { for(String key : intsances.keySet()) { if(propertyDesc.getPropertyType().isAssignableFrom(intsances.get(key).getClass())) { value = intsances.get(key); break; } } } } setter.setAccessible(true); setter.invoke(bean, value); } Field[] fields = bean.getClass().getDeclaredFields(); for(Field field : fields) { if(field.isAnnotationPresent(MyResource.class)) { MyResource myResource = field.getAnnotation(MyResource.class); Object value = null; if(myResource.name() != null && !"".equals(myResource.name())) { value = intsances.get(myResource.name()); }else { value = intsances.get(field.getName()); if(value == null) { for(String key : intsances.keySet()) { if(field.getType().isAssignableFrom(intsances.get(key).getClass())) { value = intsances.get(key); break; } } } } field.setAccessible(true); field.set(bean, value); } } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 注入属性的值 */ private void Injected() { for(BeanDefinition beanDefinition : beanDefinitions) { Object bean = intsances.get(beanDefinition.getId()); if(bean != null) { try { //通过Java的内省机制获取到对象中所有属性的描述信息 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()) { for(PropertyDescriptor propertyDesc : ps) { //判断XML文件中解析出来的属性和对象中的属性名称是否一样 if(propertyDefinition.getName().equals(propertyDesc.getName())) { //获取属性的setter方法 Method setter = propertyDesc.getWriteMethod(); if(setter != null) { Object value = null; //如果property中没有ref属性,那么表示后面将进行的是基本属性的装配 if(propertyDefinition.getRef() != null && !"".equals(propertyDefinition.getRef().trim())) { value = intsances.get(propertyDefinition.getRef()); }else { value = ConvertUtils.convert(propertyDefinition.getValue(), propertyDesc.getPropertyType()); } setter.setAccessible(true); //调用对象的setter方法赋值 setter.invoke(bean, value); } break; } } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 通过反射获取bean的实例 */ private void instanceBeans() { for(BeanDefinition beanDefinition : beanDefinitions) { try { if(beanDefinition.getClazz() != null && !"".equals(beanDefinition.getClazz())) { intsances.put(beanDefinition.getId(), Class.forName(beanDefinition.getClazz()).newInstance()); } } catch (Exception e) { e.printStackTrace(); } } } /** * 读取配置信息并将bean信息的描述对象存储到List中 * @param configFileName */ @SuppressWarnings("unchecked") private void readConfig(String configFileName) { Document document=null; Map<String,String> nsMap = new HashMap<String,String>(); try{ document = new SAXReader().read(this.getClass().getClassLoader().getResource(configFileName)); 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"); //设置命名空间 propertysub.setNamespaceURIs(nsMap); List<Element> properties = propertysub.selectNodes(element); for(Element property : properties) { String propertyName = property.attributeValue("name"); String propertyRef = property.attributeValue("ref"); String propertyValue = property.attributeValue("value"); PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyRef,propertyValue); beanDefine.getPropertys().add(propertyDefinition); } beanDefinitions.add(beanDefine); } }catch(Exception e){ e.printStackTrace(); } } /** * 外界获取bean对象的接口 */ public Object getBean(String beanName) { return this.intsances.get(beanName); } }
相关推荐
Spring注解@Resource和@Autowired.doc
spring使用@Resource所需包
Spring 三种依赖注入方式.doc Spring 三种依赖注入方式.doc
spring 控制反转和依赖注入进行基础知识的生命周期、延迟初始化、装配方式等进行案例总结使用。从而对spring基础知识更加理解。
SpringIOC_泛型依赖注入,泛型依赖注入,注入一个组件的时候,他的泛型也是参考标准
Spring依赖注入——java项目中使用spring注解方式进行注入.rar
主要介绍了Spring实战之使用@Resource配置依赖操作,结合实例形式分析了Spring使用@Resource配置依赖具体步骤、实现及测试案例,需要的朋友可以参考下
java Spring DI依赖注入.rar
主要介绍了详解Spring关于@Resource注入为null解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
spring框架-必要依赖包.rar - RAR 压缩文件, 解包大小为 2,842,394 字节 包括: -------------------------------------- commons-logging-1.1.1.jar spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0....
Classes contained in spring-mock.jar: org.springframework.mock.jndi.ExpectedLookupTemplate.class org.springframework.mock.jndi.SimpleNamingContext.class org.springframework.mock.jndi....
通过@Bean 和spring的factoryBean注入的bean. 以及对应@service注解注入的类 通过@Autowired 注入对象的时间是现根据类型在根据beanName获取的案例集合
spring框架的@Resource和@Componentspring框架的@Resource和@Component
NULL 博文链接:https://forestqqqq.iteye.com/blog/2235292
1.@Resource是按名称进行注入的,属于java自带的。@Autowired是按类型进行注入的,属于Spring。
模拟Spring IOC 自己实现依赖注入 自己的Spring 自己的代码模拟spring的依赖注入 自己写的 绝对独一无二
Spring依赖注入笔记,思维导图方式!还是比较全面的,->就是想简单分享给大家!!!
Spring @compenent注解详解,对应我的相关博客。注意,不包含相关的依赖包
org.springframework.aop-3.0.4.RELEASE.jar org.springframework.asm-3.0.4.RELEASE.jar org.springframework.aspects-3.0.4.RELEASE.jar org.springframework.beans-3.0.4.RELEASE.jar org.springframework....
Spring 依赖注入,简单,通俗易懂。 尝试翻译,欢迎拍砖。