您好,登錄后才能下訂單哦!
這篇文章主要講解了“Spring運作機制是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring運作機制是什么”吧!
Java代碼
public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext( "applicationContext.xml"); Animal animal = (Animal) context.getBean("animal"); animal.say(); } public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext( "applicationContext.xml"); Animal animal = (Animal) context.getBean("animal"); animal.say(); }
這段代碼你一定很熟悉吧,不過還是讓我們分析一下它吧,首先是applicationContext.xml
Java代碼
<bean id="animal" class="phz.springframework.test.Cat"> <property name="name"> <value>kitty</value> </property> </bean> <bean id="animal" class="phz.springframework.test.Cat"> <property name="name"> <value>kitty</value> </property> </bean>
他有一個類phz.springframework.test.Cat =
Java代碼
public class Cat implements Animal { private String name; public void say() { System.out.println("I am " + name + "!"); } public void setName(String name) { this.name = name; } } public class Cat implements Animal { private String name; public void say() { System.out.println("I am " + name + "!"); } public void setName(String name) { this.name = name; } }
實現了phz.springframework.test.Animal接口
Java代碼
public interface Animal { public void say(); } public interface Animal { public void say(); }
很明顯上面的代碼輸出I am kitty!
那么到底Spring是如何做到的呢?
接下來就讓我們自己寫個Spring 來看看Spring運作機制吧!
首先,我們定義一個Bean類,這個類用來存放一個Bean擁有的屬性
Java代碼
/* Bean Id */ private String id; /* Bean Class */ private String type; /* Bean Property */ private Map<String, Object> properties = new HashMap<String, Object>(); /* Bean Id */ private String id; /* Bean Class */ private String type; /* Bean Property */ private Map<String, Object> properties = new HashMap<String, Object>();
一個Bean包括id,type,和Properties。
接下來Spring 就開始加載我們的配置文件了,將我們配置的信息保存在一個HashMap中,HashMap的key就是Bean 的 Id ,HasMap 的value是這個Bean,只有這樣我們才能通過context.getBean("animal")這個方法獲得Animal這個類。我們都知道Spirng可以注入基本類型,而且可以注入像List,Map這樣的類型,接下來就讓我們以Map為例看看Spring是怎么保存的吧
Map配置可以像下面的
Java代碼
<bean id="test" class="Test"> <property name="testMap"> <map> <entry key="a"> <value>1</value> </entry> <entry key="b"> <value>2</value> </entry> </map> </property> </bean> <bean id="test" class="Test"> <property name="testMap"> <map> <entry key="a"> <value>1</value> </entry> <entry key="b"> <value>2</value> </entry> </map> </property> </bean>
Spring運作機制中是怎樣保存上面的配置呢?,代碼如下:
Java代碼
if (beanProperty.element("map") != null) { Map<String, Object> propertiesMap = new HashMap<String, Object>(); Element propertiesListMap = (Element) beanProperty .elements().get(0); Iterator<?> propertiesIterator = propertiesListMap .elements().iterator(); while (propertiesIterator.hasNext()) { Element vet = (Element) propertiesIterator.next(); if (vet.getName().equals("entry")) { String key = vet.attributeValue("key"); Iterator<?> valuesIterator = vet.elements() .iterator(); while (valuesIterator.hasNext()) { Element value = (Element) valuesIterator.next(); if (value.getName().equals("value")) { propertiesMap.put(key, value.getText()); } if (value.getName().equals("ref")) { propertiesMap.put(key, new String[] { value .attributeValue("bean") }); } } } } bean.getProperties().put(name, propertiesMap); } if (beanProperty.element("map") != null) { Map<String, Object> propertiesMap = new HashMap<String, Object>(); Element propertiesListMap = (Element) beanProperty .elements().get(0); Iterator<?> propertiesIterator = propertiesListMap .elements().iterator(); while (propertiesIterator.hasNext()) { Element vet = (Element) propertiesIterator.next(); if (vet.getName().equals("entry")) { String key = vet.attributeValue("key"); Iterator<?> valuesIterator = vet.elements() .iterator(); while (valuesIterator.hasNext()) { Element value = (Element) valuesIterator.next(); if (value.getName().equals("value")) { propertiesMap.put(key, value.getText()); } if (value.getName().equals("ref")) { propertiesMap.put(key, new String[] { value .attributeValue("bean") }); } } } } bean.getProperties().put(name, propertiesMap); }
接下來就進入最核心部分了,讓我們看看Spring 到底是怎么依賴注入的吧,其實依賴注入的思想也很簡單,它是通過反射機制實現的,在實例化一個類時,它通過反射調用類中set方法將事先保存在HashMap中的類屬性注入到類中。讓我們看看具體它是怎么做的吧。
首先實例化一個類,像這樣
Java代碼
public static Object newInstance(String className) { Class<?> cls = null; Object obj = null; try { cls = Class.forName(className); obj = cls.newInstance(); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } return obj; } public static Object newInstance(String className) { Class<?> cls = null; Object obj = null; try { cls = Class.forName(className); obj = cls.newInstance(); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } return obj; }
接著它將這個類的依賴注入進去,像這樣
Java代碼
public static void setProperty(Object obj, String name, String value) { Class<? extends Object> clazz = obj.getClass(); try { String methodName = returnSetMthodName(name); Method[] ms = clazz.getMethods(); for (Method m : ms) { if (m.getName().equals(methodName)) { if (m.getParameterTypes().length == 1) { Class<?> clazzParameterType = m.getParameterTypes()[0]; setFieldValue(clazzParameterType.getName(), value, m, obj); break; } } } } catch (SecurityException e) { throw new RuntimeException(e); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } public static void setProperty(Object obj, String name, String value) { Class<? extends Object> clazz = obj.getClass(); try { String methodName = returnSetMthodName(name); Method[] ms = clazz.getMethods(); for (Method m : ms) { if (m.getName().equals(methodName)) { if (m.getParameterTypes().length == 1) { Class<?> clazzParameterType = m.getParameterTypes()[0]; setFieldValue(clazzParameterType.getName(), value, m, obj); break; } } } } catch (SecurityException e) { throw new RuntimeException(e); } catch (IllegalArgumentException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } }
***它將這個類的實例返回給我們,我們就可以用了。我們還是以Map為例看看它是怎么做的,我寫的代碼里面是創建一個HashMap并把該HashMap注入到需要注入的類中,像這樣,
Java代碼
if (value instanceof Map) { Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet() .iterator(); Map<String, Object> map = new HashMap<String, Object>(); while (entryIterator.hasNext()) { Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next(); if (entryMap.getValue() instanceof String[]) { map.put((String) entryMap.getKey(), getBean(((String[]) entryMap.getValue())[0])); } } BeanProcesser.setProperty(obj, property, map); } if (value instanceof Map) { Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet() .iterator(); Map<String, Object> map = new HashMap<String, Object>(); while (entryIterator.hasNext()) { Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next(); if (entryMap.getValue() instanceof String[]) { map.put((String) entryMap.getKey(), getBean(((String[]) entryMap.getValue())[0])); } } BeanProcesser.setProperty(obj, property, map); }
感謝各位的閱讀,以上就是“Spring運作機制是什么”的內容了,經過本文的學習后,相信大家對Spring運作機制是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。