类Spring IoC容器

在构建Tiny框架之初,想着是不是不要强依赖Spring?于是就写了一个类Spring的依赖注入容器,基本实现了Spring的依赖注入部分的功能,工作情况也良好,配置规范也是采用的Spring的规范。在前面一直是没有问题的,但是在做数据库业务的时候,出现问题了。做数据库,必须要考虑事务问题,而当时我的设计目标是对各种开源的ORMapping方案都不拒绝,这个时候就引入一个问题,要么自己再实现一套AOP,要么就复用Spring。当时预想的另外一个方案是核心框架采用非直接依赖Spring的方案,数据库相关的采用Spring依赖的方式。但是实际上,业务层面的Bean会依赖系统层面的Bean,这又涉及到两个容器之间的协作,这个时候,我意识到,是应该做一个取舍了。

所以果断放弃自己来做IOC和AOP方面的工作,而采用强依赖Spring来实现的方案,毕竟在现在的应用场景下,拒绝Spring就等于让别人拒绝自己。

但是,不管怎么样,在实现这个容器的过程中,还是让我对依赖注入方面有了更深的了解,因此,这两天的投入还是值得的。

下面展示一下,它实现的功能:

<beans>
	<bean id="user" name="user,user1,user2" scope="singleton"
		class="org.tinygroup.factory.config.User">
		<property name="name">
			<value>aa</value>
		</property>
		<property name="age">
			<value>12</value>
		</property>
		<property name="cat">
			<ref id="cat" />
		</property>
		<property name="cats">
			<list>
				<ref id="cat" />
			</list>
		</property>
		<property name="catSet">
			<list>
				<ref id="cat" />
			</list>
		</property>
		<property name="catMap">
			<map>
				<entry key="aa" value-ref="cat"></entry>
			</map>
		</property>
	</bean>
	<bean id="cat" scope="singleton" class="org.tinygroup.factory.config.Cat" />
	<bean id="cat1" scope="prototype" class="org.tinygroup.factory.config.Cat" />
	<bean id="aaa1" scope="singleton" class="org.tinygroup.factory.config.Aaa">
		<property name="name">
			<value>aaa1</value>
		</property>
	</bean>
	<bean id="aaa" scope="singleton" class="org.tinygroup.factory.config.Aaa">
		<property name="name">
			<value>aaa</value>
		</property>
	</bean>
	<bean id="bbb" scope="singleton" class="org.tinygroup.factory.config.Bbb"
		autowire="byType" />
	<bean id="ccc" scope="singleton" class="org.tinygroup.factory.config.Ccc"
		autowire="byName" />
	<bean id="user2" name="user,user1,user2" scope="prototype"
		class="org.tinygroup.factory.config.User">
		<property name="name">
			<value>aa1</value>
		</property>
		<property name="age">
			<value>121</value>
		</property>
		<property name="cat">
			<ref id="cat1" />
		</property>
	</bean>
</beans>
可以看到,配置与Spring是兼容的。

下面是一些测试用例:

public void testAutoAssemble() {
 assertNotNull(factory.getBean("aaa"));
 Bbb bbb = factory.getBean("bbb");
 assertEquals("aaa", bbb.getAaa().getName());
 bbb = factory.getBean("bbb");
 assertEquals("aaa", bbb.getAaa().getName());
 Ccc ccc = factory.getBean("ccc");
 assertEquals("aaa1", ccc.getAaa1().getName());
 ccc = factory.getBean("ccc");
 assertEquals("aaa1", ccc.getAaa1().getName());
 }


 public void testInitComparePrototype() {
 Cat cat = factory.getBean("cat1");
 Cat cat1 = factory.getBean("cat1");
 assertEquals(false, cat == cat1);
 }


 public void testInitComparePrototype1() {
 User user = factory.getBean("user2");
 User user2 = factory.getBean("user2");
 assertEquals(false, user == user2);
 assertEquals(false, user.getCatMap() == user2.getCat());
 }

小结:确实,现在要脱离Spring自己再实现一个容器,越来越不合适了,毕竟Spring的用户群在那里,大家都已经熟悉适用的东西,不管是从学习成本各方面都不会选择一个新东西。

OK,虽然是一个失败的实践,但是自己实现与看Spring源码的差别还是有的,就当是一次学习吧。当然,如果是在嵌入式系统或者受限制使用的环境中,只想使用IoC,还是有用处的,毕竟 20K大小的容量还是相当诱人的。

你可能感兴趣的:(spring,J2EE,IOC,依赖注入,容器)