60 seconds to Spring

60 seconds to Spring


Introduction

Spring is a layered Java/J2EE application framework, based on code published in Expert One-on-One J2EE Design and Development by Rod Johnson (Wrox, 2002).

This a series of very short tutorial giving you a jump start understanding of Spring Framework in 60 seconds (per tutorial). It does not go into why you should do it, read the Spring Reference Documentation for that.



Pre-requisites

Before running any of the tutorial on your machine, you need to get the below few thing done first.



Tutorials Source Code

60sec2Spring.zip (spring.jar included)



Tutorials

Bean Tutorial 1 - Hello World Bean

Bean Tutorial 2 - To Singleton or Not To Singleton

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

第一个例子,就是用xml文件创建bean,再也不用自己写factory了。

第二个例子就更简单
singleton:就相当于static

第三个例子,第一个例子解决了对象创建的问题,现在就是依赖bean的调用问题,
依赖bean有两种方式调用,一种是构造函数,一种是set方法,
这没什么特殊的,我在swing中大量使用过。
但奇怪的是,在main方法中没有调用set或者构造方法。
这里同样是用xml创建了bean,并且还隐秘的创建了依赖bean(他已经自动找到了),不需要我们再调用(不要再找他),呵呵,不只是省力,更体现了IoC吧。

reference提到了三种Injection的形式,它们分别是Interface Injection、Setter Injection和Constructor Injection,对应着IoC中谈到的type 1、type 2、type 3。除了Interface Injection由于较强的侵略性,其它的两种形式,并没有什么不同。Spring和Pico都实现了这两种形式的Injection,只是Spring推崇Setter Injection,而Pico倾向于Constructor Injection。
当两个组件需要相互通信时,Setter Injection表现得明显要比Constructor Injection好。

60 sec to Spring [TOC]


Bean Tutorial 1 - Hello World Bean

This tutorial show you how to call a Hello World Bean using Spring IoC.

Step 1: Create a HelloBean.java in src

org/jarchitect/spring/tutorial1/HelloBean.java

package org.jarchitect.spring.tutorial1;

public class HelloBean {
   public String sayHelloWorld() {
      return "Hello World";
   }
}

Step 2: 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 1</description>
        <bean id="helloBean" class="org.jarchitect.spring.tutorial1.HelloBean"/>
</beans>

Step 3: Create a Main.java in src

org/jarchitect/spring/tutorial1/Main.java

package org.jarchitect.spring.tutorial1;

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 an object
         HelloBean helloBean = (HelloBean) factory.getBean("helloBean");

         //Execute the public method of the HelloBean
         System.out.println(helloBean.sayHelloWorld());
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      }
   }
}

Step 4: 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/SpringTutorial1>ant
Buildfile: build.xml

build:
    [javac] Compiling 2 source files to C:/60sec2Spring/SpringTutorial1/bin
run:
     [java] May 18, 2004 2:25:14 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
     [java] INFO: Loading XML bean definitions from (no description)
     [java] May 18, 2004 2:25:15 PM org.springframework.beans.factory.support.AbstractBeanFactory getBean
     [java] INFO: Creating shared instance of singleton bean 'helloBean'
     [java] Hello World



BUILD SUCCESSFUL
Total time: 3 second

Done.

[TOC]


Bean Tutorial 2 - To Singleton or Not To Singleton

Beans are defined to be deployed in one of the two modes: Singleton and Non-Singleton (Prototype). When a bean is a singleton, only one shared instance of the bean will be managed. The prototype mode of a bean deployment results in the creation of a new bean instance every time a request for that specific bean is done. Tutorial 2 will demostrate the difference behaviour when defining a bean as Singleton and Prototype.

Note: By default all beans are deployed in singleton mode, unless you specify otherwise.

Step 1: Create a CounterBean.java in src

org/jarchitect/spring/tutorial2/CounterBean.java

package org.jarchitect.spring.tutorial2;

public class CounterBean {
   private int counter;

   public CounterBean() {
      System.out.println("Construct CounterBean......");
   }

   public int getCount() {
      return counter++;
   }
}

Step 2: Specify the CounterBean class in the bean.xml

Do notice that I have defined one CounterBean as singleton bean and the other as prototype bean.

<?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 2</description>
        <bean id="singletonBean" class="org.jarchitect.spring.tutorial2.CounterBean" singleton="true"/>
        <bean id="prototypeBean" class="org.jarchitect.spring.tutorial2.CounterBean" singleton="false"/>
</beans>

Step 3: Create a Main.java in src

org/jarchitect/spring/tutorial2/Main.java

package org.jarchitect.spring.tutorial2;

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 an singleton object
         System.out.println("---- Singleton Bean ----");

         CounterBean singletonBean =
            (CounterBean) factory.getBean("singletonBean");
         System.out.println("First Call  :- " + singletonBean.getCount());

         singletonBean = (CounterBean) factory.getBean("singletonBean");
         System.out.println("Second Call :- " + singletonBean.getCount());

         System.out.println("");

         //Instantiate an object
         System.out.println("---- Prototype Bean ----");

         CounterBean prototypeBean =
            (CounterBean) factory.getBean("prototypeBean");
         System.out.println("First Call  :- " + prototypeBean.getCount());

         prototypeBean = (CounterBean) factory.getBean("prototypeBean");
         System.out.println("Second Call :- " + prototypeBean.getCount());
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      }
   }
}

Step 4: 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/SpringTutorial2>ant
Buildfile: build.xml

build:
    [javac] Compiling 2 source files to C:/60sec2Spring/SpringTutorial2/bin

run:
     [java] Jun 1, 2004 12:16:42 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
     [java] INFO: Loading XML bean definitions from (no description)
     [java] Jun 1, 2004 12:16:42 PM org.springframework.beans.factory.support.AbstractBeanFactory getBean
     [java] INFO: Creating shared instance of singleton bean 'singletonBean'
     [java] ---- Singleton Bean ----
     [java] Construct CounterBean......
     [java] First Call  :- 0
     [java] Second Call :- 1

     [java] ---- Prototype Bean ----
     [java] Construct CounterBean......
     [java] First Call  :- 0
     [java] Construct CounterBean......
     [java] Second Call :- 0



BUILD SUCCESSFUL
Total time: 2 seconds

Done.

[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]


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值