CSDN博客

img JasonSeaver

60 seconds to Spring (3)

发表于2004/7/6 23:26:00  762人阅读

分类: Framework

60 sec to Spring [TOC]

Bean Tutorial 3 - Setter-Based and Construction-Based Dependency Injection

Inversion of Control/Dependency Injection exists in two major variants:

  • Setter-based dependency injection is realized by calling setters on your beans after invoking a no-argument constructor to instantiate your bean. Beans defined in the BeanFactory that use setter-based dependency injection are true JavaBeans. Spring generally advocates usage of setter-based dependency injection, since a large number of constructor arguments can get unwieldy, especially when some properties are optional.

  • Constructor-based dependency injection is realized by invoking a constructor with a number of arguments, each representing a collaborator or property.


Step 1: We will need two dummy classes for our tutorial, AnotherBean.java and YetAnotherBean.java.

org/jarchitect/spring/tutorial3/AnotherBean.java

package org.jarchitect.spring.tutorial3; public class AnotherBean { public AnotherBean() { System.out.println("Construct AnotherBean"); } }

org/jarchitect/spring/tutorial3/YetAnotherBean.java

package org.jarchitect.spring.tutorial3; public class YetAnotherBean {  public YetAnotherBean() {  System.out.println("Construct YetAnotherBean"); } }

Step 2: We will create a ConstructorExampleBean and a SetterExampleBean.

org/jarchitect/spring/tutorial3/ConstructorExampleBean.java

package org.jarchitect.spring.tutorial3; public class ConstructorExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public ConstructorExampleBean( AnotherBean anotherExampleBean, YetAnotherBean yetAnotherBean, int i) { this.beanOne = anotherExampleBean; this.beanTwo = yetAnotherBean; this.i = i; System.out.println("Construction Done!!!"); } public ConstructorExampleBean() { System.out.println("Default Constructor : Should not be call!!!"); } }

org/jarchitect/spring/tutorial3/SetterExampleBean.java

package org.jarchitect.spring.tutorial3; public class SetterExampleBean { private AnotherBean beanOne; private YetAnotherBean beanTwo; private int i; public SetterExampleBean() { System.out.println("Default Constructor"); } public void setBeanOne(AnotherBean bean) { this.beanOne = bean; System.out.println("Set beanOne"); } public void setBeanTwo(YetAnotherBean bean) { this.beanTwo = bean; System.out.println("Set beanTwo"); } public void setIntegerProperty(int i) { this.i = i; System.out.println("Set i"); } }

Step 3: Specify the HelloBean class in the bean.xml

bean.xml

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>  <description>jarchitect Spring Tutorial 3</description> <bean id="setterBean" class="org.jarchitect.spring.tutorial3.SetterExampleBean"> <description>Setter-based Dependency Injection.</description> <property name="beanOne"><ref bean="anotherExampleBean"/></property> <property name="beanTwo"><ref bean="yetAnotherBean"/></property> <property name="integerProperty"><value>1</value></property> </bean> <bean id="constructorBean" class="org.jarchitect.spring.tutorial3.ConstructorExampleBean"> <description>Constructor Dependency Injection</description> <constructor-arg><ref bean="yetAnotherBean"/></constructor-arg> <constructor-arg><ref bean="anotherExampleBean"/></constructor-arg> <constructor-arg index="2"><value>1</value></constructor-arg> </bean> <bean id="anotherExampleBean" class="org.jarchitect.spring.tutorial3.AnotherBean"/> <bean id="yetAnotherBean" class="org.jarchitect.spring.tutorial3.YetAnotherBean"/> </beans>

Step 4: reate a Main.java in src

org/jarchitect/spring/tutorial3/Main.java

package org.jarchitect.spring.tutorial3; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import org.springframework.beans.factory.xml.XmlBeanFactory; public class Main { public static void main(String[] args) { try { //Read the configuration file InputStream is = new FileInputStream("bean.xml"); XmlBeanFactory factory = new XmlBeanFactory(is); //Instantiate SetterExampleBean SetterExampleBean setterBean = (SetterExampleBean) factory.getBean("setterBean"); //Instantiate ConstructorExampleBean ConstructorExampleBean constructorBean = (ConstructorExampleBean) factory.getBean("constructorBean"); } catch (FileNotFoundException e) { e.printStackTrace(); } } }

Step 5: Use an ANT script to build and execute the Main class. Just run ant from the command prompt will do the trick.

Below are the output from ANT.

C:/60sec2Spring/SpringTutorial3>ant Buildfile: build.xml build: [javac] Compiling 5 source files to C:/60sec2Spring/SpringTutorial3/bin run: [java] Jun 1, 2004 12:36:51 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions [java] INFO: Loading XML bean definitions from (no description) [java] Jun 1, 2004 12:36:51 PM org.springframework.beans.factory.support.AbstractBeanFactory getBean [java] INFO: Creating shared instance of singleton bean 'setterBean' [java] Default Constructor [java] Construct AnotherBean [java] Jun 1, 2004 12:36:51 PM org.springframework.beans.factory.support.AbstractBeanFactory getBean [java] INFO: Creating shared instance of singleton bean 'anotherExampleBean' [java] Construct YetAnotherBean [java] Set beanOne [java] Set beanTwo [java] Jun 1, 2004 12:36:51 PM org.springframework.beans.factory.support.AbstractBeanFactory getBean [java] INFO: Creating shared instance of singleton bean 'yetAnotherBean' [java] Set i [java] Jun 1, 2004 12:36:51 PM org.springframework.beans.factory.support.AbstractBeanFactory getBean [java] INFO: Creating shared instance of singleton bean 'constructorBean' [java] Construction Done!!! [java] Jun 1, 2004 12:36:51 PM org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory autowireConstructor [java] INFO: Bean 'constructorBean' instantiated via constructor [public org.jarchitect.spring.tutorial3. ConstructorExampleBean(org.jarchitect.spring.tutorial3.AnotherBean,org.jarchitect.spring.tutorial3.YetAnotherBean,int)] BUILD SUCCESSFUL Total time: 2 seconds

Overtime

From bean.xml

...... <bean id="constructorBean" class="org.jarchitect.spring.tutorial3.ConstructorExampleBean"> <description>Constructor Dependency Injection</description> <constructor-arg><ref bean="yetAnotherBean"/></constructor-arg> <constructor-arg><ref bean="anotherExampleBean"/></constructor-arg> <constructor-arg index="2"><value>1</value></constructor-arg> </bean> ......

Notice the index="2", try removing it and run ANT again. You will have the following error.

....... [java] INFO: Creating shared instance of singleton bean 'constructorBean' [java] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'constructorBean' defined in (no description): 3 constructor arguments specified but no matching constructor found in bean 'constructorBean'(hint: specify index arguments for simple parameters to avoid type ambiguities) [java] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. autowireConstructor(AbstractAutowireCapableBeanFactory.java:287) [java] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory. createBean(AbstractAutowireCapableBeanFactory.java:181) [java] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:159) [java] at org.jarchitect.spring.tutorial3.Main.main(Unknown Source) [java] Exception in thread "main" [java] Java Result: 1 BUILD SUCCESSFUL Total time: 1 second

Reason: The argument is an int, but BeanFactory take it as a String, so the mapping isn't obvious to the matching algorithm. In case of primitives, it's recommended to specify the argument index explicitly.

More Reason: For example, constructors MyClass(bool flag, String toto, int moo, float cow). There is no way for the BeanFactory to tell which is which from the string representations of each.

Next, try swapping

 <constructor-arg index="2"><value>1</value></constructor-arg>  <constructor-arg><ref bean="anotherExampleBean"/></constructor-arg>  <constructor-arg><ref bean="yetAnotherBean"/></constructor-arg>

and run ANT.

Done.

[TOC]

0 0

相关博文

我的热门文章

img
取 消
img