本次要向大家介绍一下Spring的注入,包括属性注入,对象注入,构造方法注入,集合注入。在介绍之前,先做一些准备工作。
首先新建一个JAVA项目,名为SpringDemo。
然后为项目导入Spring开发包(目前最新的是3.2.0版本),光导入Spring包还不够,需要下载commons-logging开发包。
Spring:http://www.springsource.org/download/community
commons-logging:http://commons.apache.org/logging/download_logging.cgi
在进行注入演示之前,我们需要一个测试类,这里我们写一个简单的三角形(Triangle)类.
package zjut.edu.spring; public class Triangle { private String type; public String getType() { return type; } public void setType(String type) { this.type = type; } }
再来是含有main方法的测试类:
package zjut.edu.spring; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { /** * @param args */ public static void main(String[] args) { BeanFactory factory = new ClassPathXmlApplicationContext("springconfig.xml"); Triangle triangle = (Triangle) factory.getBean("triangle"); System.out.println(triangle.getType()); } }
main方法里的代码不懂没关系,下面会进行讲解的。
一. 属性注入:
通常我们如果想要获得一个Triangle类的实例,我们会这样来写。
Triangle triangle = new Triangle();
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="triangle" class="zjut.edu.spring.Triangle"> <property name="type" value="saojiaoxing"/> </bean> </beans>
如果我们想要实现属性注入,需要写自己的bean:
<bean id="triangle" class="zjut.edu.spring.Triangle"> <property name="type" value="sanjiaoxing"/> </bean>
bean标签里的id属性代表实例名称,class属性代表类的全路径(full qualified name),接下来,在bean标签内部有一个property子标签,负责为属性赋值,name对应于Triangle类的属性名(type),value属性顾名思义为属性值。
配置文件配好后,要想得到该bean,我们需要先读取配置文件:
BeanFactory factory = new ClassPathXmlApplicationContext("springconfig.xml");
因为ClassPathXmlApplicationContext负责读取类路径下的xml文件,所以spring配置文件必须放在src目录下(当然String API 下还有其它的类不需要将配置文件放在src目录下),该类返回的是一个bean工厂,该工厂读取配置文件后负责返回bean对象。
Triangle triangle = (Triangle) factory.getBean("triangle");
System.out.println(triangle.getType());
运行一下,看看:
十一月 19, 2012 10:46:34 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1263db: startup date [Mon Nov 19 22:46:34 CST 2012]; root of context hierarchy 十一月 19, 2012 10:46:34 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [springconfig.xml] 十一月 19, 2012 10:46:35 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@36eb76: defining beans [triangle]; root of factory hierarchy sanjiaoxing
package zjut.edu.spring; public class Triangle { private Point point; public Point getPoint() { return point; } public void setPoint(Point point) { this.point = point; } public void draw() { System.out.println(point); } }
我们将type属性取消掉,换成一个Point类型的字段(因为三角形有点):
package zjut.edu.spring; public class Point { private int x; private int y; public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } @Override public String toString() { return "Point [x=" + x + ", y=" + y + "]"; } }
我们的Point类也很简单,有横纵坐标,并且覆盖了toString()方法(为了测试数据用)
现在我们依然想将Point注入到Triangle类中,在配置文件中,我们应该这样来写bean
<bean id="triangle" class="zjut.edu.spring.Triangle"> <property name="point"> <bean class="zjut.edu.spring.Point"> <property name="x" value="1" /> <property name="y" value="2" /> </bean> </property> </bean>
当然,我们也可以将内部bean和triangle的bean平行.
<bean id="triangle" class="zjut.edu.spring.Triangle"> <property name="point" ref="point0"></property> </bean> <bean id="point0" class="zjut.edu.spring.Point"> <property name="x" value="1" /> <property name="y" value="2" /> </bean>
配置好bean后,我们在主类中测试下:
public static void main(String[] args) { BeanFactory factory = new ClassPathXmlApplicationContext("springconfig.xml"); Triangle triangle = (Triangle) factory.getBean("triangle"); triangle.draw(); }
十一月 19, 2012 10:59:06 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1263db: startup date [Mon Nov 19 22:59:06 CST 2012]; root of context hierarchy 十一月 19, 2012 10:59:07 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [springconfig.xml] 十一月 19, 2012 10:59:07 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@161116f: defining beans [triangle,point0]; root of factory hierarchy Point [x=1, y=2]
就像Servlet容器管理servlet一样,bean的生命周期也是由Spring容器管理的。如果我们想要通过初始化的方法对属性赋值,我们应该这样来写bean.
我们改写下Triangle:
package zjut.edu.spring; public class Triangle { private String type; public Triangle(String type) { this.type = type; } public void draw() { System.out.println(type); } }
为了简单点,这里的构造方法的参数为String类型,(Object类型的可以自己去试一下)
<bean id="triangle" class="zjut.edu.spring.Triangle"> <constructor-arg index="0" value="I'm triangle"></constructor-arg> </bean>
constructor-arg标签就是构造方法注入的核心标签,index属性表示参数的位置,value表示参数值(还有type属性,说明该参数的类型)
最后一个注入:集合注入,我们再改一下Triangle类:
package zjut.edu.spring; import java.util.List; public class Triangle { private List<Point> points; public List<Point> getPoints() { return points; } public void setPoints(List<Point> points) { this.points = points; } public void draw() { for(Point point : points) { System.out.println(point); } } }
<bean id="triangle" class="zjut.edu.spring.Triangle"> <property name="points"> <list> <ref bean="point0"/> <ref bean="point1"/> <ref bean="point2"/> </list> </property> </bean> <bean id="point0" class="zjut.edu.spring.Point"> <property name="x" value="0" /> <property name="y" value="20"/> </bean> <bean id="point1" class="zjut.edu.spring.Point"> <property name="x" value="0" /> <property name="y" value="-20"/> </bean> <bean id="point2" class="zjut.edu.spring.Point"> <property name="x" value="10" /> <property name="y" value="10"/> </bean>
看下我们的输出:
Point [x=0, y=20] Point [x=0, y=-20] Point [x=10, y=10]
Over... 勉強を続けている!