浅析spring中注解的运行
2016-03-25 16:34
405 查看
为了了解注解的运行机制,需要自定义一个注解,如下方式来模拟注解方式实现注入对象:
1.新建一个自定义注解MyResource.java
2.自定义spring中的注解运行
输出的结果和使用j2ee的注解有相同的效果
1.新建一个自定义注解MyResource.java
@Retention(RetentionPolicy.RUNTIME) // 定义注解有效期为运行期 @Target({ElementType.FIELD,ElementType.METHOD}) // 定义可以注解的位置 public @interface MyResource { String name() default ""; }
2.自定义spring中的注解运行
package com.heying.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; import com.heying.service.MyResource; import com.heying.service.PropertyDdefinition; import com.heying.service.XmlBeanDefinition; public class MyClassPathXmlApplicationContext { private List<XmlBeanDefinition> beanDefinitions = new ArrayList<XmlBeanDefinition>(); private Map<Object, Object> sigletons = new HashMap<Object, Object>(); public MyClassPathXmlApplicationContext(String fileName) { this.readXmlFile(fileName); this.instanceBeans(); this.annotationInject(); this.injectObject(); } /** * 注解 */ private void annotationInject() { for (Object beanName : sigletons.keySet()) { Object bean = sigletons.get(beanName); if(bean != null){ try { PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for (PropertyDescriptor propertyDescriptor : ps) { Method setter = propertyDescriptor.getWriteMethod(); if(setter != null && setter.isAnnotationPresent(MyResource.class)){ MyResource myTest = setter.getAnnotation(MyResource.class); //获取注解 if(myTest.name() != null && !"".equals(myTest.name())){ Object value = sigletons.get(myTest.name()); setter.setAccessible(true); setter.invoke(bean,value); // 引入对象到属性 }else{ Object value = sigletons.get(propertyDescriptor.getName()); // 没有标注name 或者没有找到的时候就会按照类型去寻找 if(value == null){ for (Object key : sigletons.keySet()) { if(propertyDescriptor.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){ value = sigletons.get(key); setter.setAccessible(true); setter.invoke(bean,value); // 引入对象到属性 break; } } } } } } Field[] fields = bean.getClass().getDeclaredFields(); for (Field field : fields) { if(field.isAnnotationPresent(MyResource.class)){ MyResource myTest = field.getAnnotation(MyResource.class); //获取注解 Object value = null; if(myTest.name() != null && !"".equals(myTest.name())){ value = sigletons.get(myTest.name()); }else{ value = sigletons.get(field.getName()); // 没有标注name 或者没有找到的时候就会按照类型去寻找 if(value == null){ for (Object key : sigletons.keySet()) { if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){ value = sigletons.get(key); break; } } } } field.setAccessible(true); field.set(bean, value); } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 依赖注入 */ private void injectObject() { for ( XmlBeanDefinition beanDefinition : beanDefinitions) { Object bean = sigletons.get(beanDefinition.getId()); if(bean != null){ try { PropertyDescriptor[] propers = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for (PropertyDdefinition propertyDdefinition : beanDefinition.getDdefinitions()) { for (PropertyDescripto 4000 r propertyDescriptor : propers) { if(propertyDdefinition.getName().equals(propertyDescriptor.getName())){ // 判断是否相等 Method setter = propertyDescriptor.getWriteMethod(); // 获取set方法 if(setter != null){ Object value = sigletons.get(propertyDdefinition.getRef()); setter.setAccessible(true); setter.invoke(bean,value); // 引入对象到属性 } break; } } } } catch (Exception e) { e.printStackTrace(); } } } } /** * bean 实例化 */ private void instanceBeans(){ for ( XmlBeanDefinition beanDefinition : beanDefinitions) { try { if(beanDefinition.getName() != null && !"".equals(beanDefinition.getName())){ sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getName()).newInstance()); } } catch (Exception e) { e.printStackTrace(); } } } /** * 读取XML信息 * @param fileName */ @SuppressWarnings("unchecked") private void readXmlFile(String fileName) { SAXReader saxReader = new SAXReader(); Document document = null; try { URL xmlPath = this.getClass().getClassLoader().getResource(fileName); // 获取相对路径 document = saxReader.read(xmlPath); // 读取xml文件 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); // 获取所有节点 for (Element element : beans) { String id = element.attributeValue("id"); String clazz = element.attributeValue("class"); XmlBeanDefinition xmlBeanDefinition = new XmlBeanDefinition(id, clazz); XPath propertysub = document.createXPath("ns:property"); propertysub.setNamespaceURIs(nsMap); // 设置空间 List<Element> propertys = propertysub.selectNodes(element); for (Element property : propertys) { String propertyName = property.attributeValue("name"); String propertyRef = property.attributeValue("ref"); System.out.println("[propertyName="+propertyName+",propertyRef="+propertyRef+"]"); PropertyDdefinition ddefinition = new PropertyDdefinition(propertyName, propertyRef); xmlBeanDefinition.getDdefinitions().add(ddefinition); } beanDefinitions.add(xmlBeanDefinition); } } catch (Exception e) { e.printStackTrace(); } } /** * 获取bean实例 * @param beanName * @return */ public Object getBean(String beanName){ return this.sigletons.get(beanName); } }
输出的结果和使用j2ee的注解有相同的效果
相关文章推荐
- 详解JDK 5 Annotation 注解之@Target的用法介绍
- java教程之java注解annotation使用方法
- Java中注解的工作原理
- Java注解之Retention、Documented、Inherited介绍
- spring aop两种配置方式
- Restful传递数组参数及注解大全
- Java @Deprecated注解的作用及传递性
- 小议Java中@param注解与@see注解的作用
- Java注解详细介绍
- 详解Java编程中Annotation注解对象的使用方法
- JDK 5 提供的注解:Target、Inherited和Documented的区别
- SpringMVC restful 注解之@RequestBody进行json与object转换
- 基于Java 注解(Annotation)的基本概念详解
- Spring常用注解汇总
- Java中三种简单注解介绍和代码实例
- 详解Java注解教程及自定义注解
- 一个奇怪的异常,SSH使用注解方式
- struts2注解配置注意事项
- Java Android 注解(Annotation) 及几个常用开源项目注解原理简析
- JQuery、ajaxFileUpload、Struts2和注解异步上传文件