DAO depend-on Database时,也可以在DAO上定义setDatabase方法来接收一个Database的实例。这样Sping会保证DAO创建前先创建Database实例,然后在把实例化DAO后调用DAO的setDatabase方法把刚才创建的Database的实例注入给DAO。前提条件时Database必须定义成单例的。否则Spring在DAO depend-on Database时会创建一个Database的实例,在DAO.setDatabase时又会创建Database另外的一个实例。这种情况可能不是你想要的,而且很可能会造成比较隐蔽的错误。
使用set方法注入depend-on的对象: <? xml version="1.0" encoding="UTF-8" ?> <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean name ="dao" class ="research.spring.beanfactory.ch3.Dao" depends-on ="database " > < property name ="database" > < ref bean ="database" ></ ref > </ property > </ bean > < bean id ="database" class ="research.spring.beanfactory.ch3.Database" > </ bean > </ beans > 一般在depends-on一个对象并且又需要这个对象实例的情况下,我都建议你使用构造函数的注入方式替换depend-on。只有不能构造函数中添加依赖对象参数的情况下才使用上面例子里的方式。 可以同时使用depends-on和构造函数注入,如A depends-on B 并且 new A(B b)。 <? xml version="1.0" encoding="UTF-8" ?> <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean name ="dao" class ="research.spring.beanfactory.ch3.Dao" depends-on ="database" > < constructor-arg > < ref bean ="database" ></ ref > </ constructor-arg > </ bean > < bean id ="database" class ="research.spring.beanfactory.ch3.Database" > </ bean > </ beans > 然而这种做法是不合适的,因为在构在函数中注入依赖对象的方式可以包含depends-on的情况。也就时说new A(B b)包含了A depends-on B的所有情况。既然已经定义了new A(B b)就没有必要在定义A depends-on B。所以, new A(B b) 可以替代 A depends-on B。 在 A 创建前必须创建 B ,而且 A 不需要使用 B 实例的情况下只能使用 A depends-on B 。Spring允许Bean和Bean依赖的Bean(合作者)上同时定义depends-on。比如A depends-on B && B depends-on C && C depends-on D。下面这样定义是合法的。Sping实例化他们的顺序是D->C->B->A。
<? xml version="1.0" encoding="UTF-8" ?> <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean name ="a" class ="research.spring.beanfactory.ch3.A" depends-on ="b" /> < bean name ="b" class ="research.spring.beanfactory.ch3.B" depends-on ="c" /> < bean name ="c" class ="research.spring.beanfactory.ch3.C" depends-on ="D" /> < bean name ="d" class ="research.spring.beanfactory.ch3.D" /> </ beans > 但是Spring不允许A depends-on B && B depends-on A的情况。看下面的例子,由于D又依赖回A,这种在依赖关系中形成了一个闭环,Spring将无法处理这种依赖关系。所以下面的这种定义是不合法的。 <? xml version="1.0" encoding="UTF-8" ?> <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean name ="a" class ="research.spring.beanfactory.ch3.A" depends-on ="b" /> < bean name ="b" class ="research.spring.beanfactory.ch3.B" depends-on ="c" /> < bean name ="c" class ="research.spring.beanfactory.ch3.C" depends-on ="D" /> < bean name ="d" class ="research.spring.beanfactory.ch3.D" depends-on ="A" /> </ beans > 一个Bean可以同时depends-on多个对象如,A depends-on D,C,B。可以使用“,”或“;”定义多个depends-on的对象。 <? xml version="1.0" encoding="UTF-8" ?> <! DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > < beans > < bean name ="a" class ="research.spring.beanfactory.ch3.A" depends-on ="d,c,b" /> < bean name ="b" class ="research.spring.beanfactory.ch3.B" /> < bean name ="c" class ="research.spring.beanfactory.ch3.C" /> < bean name ="d" class ="research.spring.beanfactory.ch3.D" /> </ beans >上面的例子中A的实例化需要先实例化D,C,B。Spring会按照depend-on中定义的顺序来处理Bean。在这个例子里Spring实例化对象的顺利是D->C->B->A。虽然实例化对象的顺序和前面“A depends-on B && B depends-on C && C depends-on D”的情况一下,但是这里的意义是完全不同的。不能用“A depends-on D,C,B”代替“A depends-on B && B depends-on C && C depends-on D”。
depends-on是一个非常又用的功能,借助depends-on我们可以管理那些依赖关系不明显或者没有直接依赖关系的对象。 发布于 2006年7月4日 16:49 由 陈杰 有 1 篇评论create user from - static factory method
这说明userDao使用它自己得静态工厂创建得。 静态工厂方法存在一些限制: 静态工厂方法上不能有参数,也不能在Spring种定义静态工厂方法的参数。 静态工厂方法只能是public的,不能是private或protected的。 静态工厂方法不能和构造函数注入一起使用。下面的定义时不能正常工作的:
package research.spring.beanfactory.ch2; import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframework.core.io.ClassPathResource; public class Test { public static void main(String[] args) { XmlBeanFactory factory=new XmlBeanFactory(new ClassPathResource("research/spring/beanfactory/ch2/context.xml")); UserManager manager=(UserManager) factory.getBean("userManager"); manager.createUser(); } }
实例工厂和静态工厂一样都存在相同的限制: 静态工厂方法上不能有参数,也不能在Spring种定义静态工厂方法的参数。 静态工厂方法只能是public的,不能是private或protected的。 静态工厂方法不能和构造函数注入一起使用。
和静态工厂不同的是: 实例工厂方法不能是静态的,而静态工厂方法必须是静态的。
通过上面的例子我们看到Spring对工厂模式对了完整的支持。但是这里还是需要说明,如果使用IoC模式设计的系统一般情况下不需要为任何Bean做工厂类。在我的观点里,工厂模式仅仅是遗留系统,使用依赖注入模式可以取代工厂模式。Spring对工厂的支持仅仅是为了可以很好的集成遗留系统。
