1. 程式人生 > >淺析spring中註解的執行

淺析spring中註解的執行

為了瞭解註解的執行機制,需要自定義一個註解,如下方式來模擬註解方式實現注入物件:
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的註解有相同的效果

相關推薦

no