手寫一個簡易的IOC

這個小項目是我讀過一點Spring的源碼後,模仿Spring的IOC寫的一個簡易的IOC,固然Spring的在天上,我寫的在馬裏亞納海溝,哈哈java

感興趣的小夥伴能夠去個人github拉取代碼看着玩git

地址: https://github.com/zhuchangwu/CIOC程序員

項目中有兩種方式實現IOC:github

  • 第一種是基於dom4j實現的解析XML配置文件版
  • 第二種是基於自定義註解實現全配置版

全註解版

模仿Spring原生的IOC機制以下:dom

  • Interface類型的beanDefinition不會被實例化**
  • String類型的beanDefinition不會被實例化
  • 維護三個核心的map容器
    • 使用底層存放實例化對象的容器是一個叫singletonObjects的CurrentHashMap
    • 第二個用來輔助解決循環依賴的容器叫singletonFactories類型:CurrentHashMap
    • 第二個用來存放bean定義信息的map容器叫beanDefinitionMap類型:CurrentHashMap

Spring底層的本身還封裝了BeanDefinition, 固然我沒幹這件事,直接用的類的描述對象 Class調試

自定義了四種註解以下:

  • CDao 用於標識持久層的對象
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CDao {
    String value()default "";
}
  • CService 用來標識服務層的對象
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CService {
    String value()default "";
}
  • CComponentScan 用來標識主配置類,提供包掃描須要的base-packet
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface CComponentScan {
    String value()default "";
}
  • CAutowired 用來標識須要自動裝配的對象
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CAutowired {
    String value()default "";
}

固然他跟Spring原生的@Autowired是無法比的,Spring自動裝配類型默認是Autowired_no, 可是被Spring原生標記上的對象會先按照默認的裝配類型進行裝配,若是沒有默認的裝配類型,再按照byType,若是容器中存在多個相同類型的對象,就按照byName, 名字再同樣就直接報錯了code

Spring是容許程序員去改這個默認的裝配類型的xml

而後在個人IOC中就比較遜色了,直接默認按照byType,沒有合適的類型再按照byName進行自動裝配對象

解決了循環依賴的問題

在我手動寫如何解決循環依賴的時候,那時候我尚未去看源碼, 當時我畫了幾個流程圖,可是仍是卡殼了, 因而我去調試Spring的實現, 簡直了!Spring的做者們簡直是真神!
其實說Spring如何解決循環依賴的,我前面有幾個源碼閱讀的博客,感興趣能夠去看看繼承

這裏我就簡單的說下, 這件事是一個叫AutowiredAnnotationBeanDefinitonPostprocessor的後置處理器完成的, Spring在作這件事是時候,前先後後是一個偌大的繼承體系在支持,可是歸根結底是Spring玩了個漂亮的遞歸,方法名是getBean(),固然這個遞歸還有幾個輔助容器,這幾個容器就是我上面說的幾個map ,個人IOC能寫成,就得益於這一點

XML版

註解版的IOC我是用DOM4j解析XML配置文件實現的, 作了下面的功能

  • 支持setter方法依賴注入

標識性的信息是 property

<bean id="dao1" class="com.changwu.dao.DaoImpl1"></bean>
<bean id="service" class="com.changwu.service.UserServiceImpl4">
    <property ref="dao1" name="daoImpl"></property>
</bean>
  • 支持構造方法的依賴注入

標識性的信息是 constructor-arg

<bean id="DaoImpl" class="com.changwu.dao.DaoImpl1"></bean>
<bean id="service" class="com.changwu.service.UserServiceImpl3">
    <constructor-arg ref ="DaoImpl" name="DaoImpl1"></constructor-arg>
</bean>
</bean>
  • 支持byType的自動裝配

標識性的信息是 byType

<beans  default-autowire="byType">
  • 主持byName的自動裝配
<beans  default-autowire="byName">

感興趣的小夥伴能夠去個人github拉取代碼看着玩

地址: https://github.com/zhuchangwu/CIOC

相關文章
相關標籤/搜索