浅析spring中注解的运行
来源:互联网 发布:mac版office登陆账号 编辑:程序博客网 时间:2024/04/28 03:46
为了了解注解的运行机制,需要自定义一个注解,如下方式来模拟注解方式实现注入对象:
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 (PropertyDescriptor 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的注解有相同的效果
0 0
- 浅析spring中注解的运行
- Spring的@RequestMapping注解类浅析
- Spring 注解浅析
- 浅析Spring中的注解
- Spring中的注解浅析!!
- Spring中注解的配置
- Spring中注解的使用
- spring中注解的使用
- Spring 中相关的注解
- spring注解配置原理浅析
- Spring浅析之注解之二:spring支持的JSR-250注解之:@PostConstruct、@PreDestroy
- 【Spring】--spring MVC中常用的注解
- 浅析Tomcat中Servlet的运行原理
- 浅析Spring中ClassPathXmlApplicationContext()的装配过程
- Spring中@Autowired注解、@Resource注解的区别
- Spring中@Autowired注解、@Resource注解的区别
- Spring中@Autowired注解、@Resource注解的区别
- Spring中@Autowired注解、@Resource注解的区别
- ElasticSearch性能优化方案
- [Mac]环境变量配置
- Elasticsearch- 分词查询
- Centos5.5安装oracle11g
- elasticsearch配置小记
- 浅析spring中注解的运行
- linux的ip地址排序
- Linux系统iNode耗尽硬盘无法写入文件怎么办?
- linux上连接的数据库命令,及解锁表
- 63.保留小数位数和精确数字(NSDecimalNumber/NSDecimalNumberHandler)
- 《HTML+CSS基础课程》学习笔记八
- 中文分词器性能比较
- ios学习总结(2) -- UIButton的使用
- 11大Java开源中文分词器的使用方法和分词效果对比