下载spring包,在eclipse搭建spring环境。
这步我在eclipse中无法导入包,看网上的:
http://sishuok.(和谐)com/forum/blogPost/list/2428.html
建一个java project
三个java文件,一个xml文件
1 package com.guigu.spring.beans; 2 3 public class HelloWord { 4 private String name; 5 public String getName() { 6 return name; 7 } 8 public void setName(String name) { 9 this.name = name; 10 } 11 public void hello(){ 12 System.out.println("hello: "+name); 13 } 14 }
1 import java.applet.AppletContext; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.AbstractApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 8 public class Main { 9 public static void main(String[] args) { 10 // 传统调用方式 11 // HelloWord h = new HelloWord(); 12 // h.setName("evan"); 13 // h.hello(); 14 //1、读取配置文件实例化一个IoC容器 ,会动态创建对象,调用构造函数,xml中有属性还会调用setname() 15 ApplicationContext context = new ClassPathXmlApplicationContext("application.xml"); 16 //2、从容器中的id获取Bean,注意此处完全“面向接口编程,而不是面向实现” 17 HelloWord hello = (HelloWord) context.getBean("helloword"); 18 //3、执行业务逻辑 19 hello.hello(); 20 } 21 22 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 9 <!-- id 表示你这个组件的名字,class表示组件类 --> 10 <bean id="helloword" class="com.guigu.spring.beans.HelloWord"> 11 <property name="name" value="Spring"></property> 12 </bean>
13</beans>
helloword是一个id标识,它属于com.guigu.spring.beans.HelloWord类,是它的一个实例。一个类可以有多个实例。所以可以有多个bean的类相同,表示一个类的不同实例。
bean中可以添加属性,用property属性
IoC容器
用的是ApplicationContext(应用上下文),它是由BeanFactory(Bean工厂)扩展而来,BeanFactory提供了IoC容器最基本功能如: getBean();
ApplicationContext扩展了BeanFactory,还提供了与Spring AOP集成、国际化处理、事件传播及提供不同层次的context实现。
【 ApplicationContext 的初始化和BeanFactory 有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean 时才实例目标Bean,即调用getBean才初始化;而ApplicationContext 则在初始化应用上下文时就实例化所有单实例的Bean 。】
(了解更多去大牛博客:http://elf8848.iteye.com/blog/324796)
ApplicationContext的实现有两个:
• ClassPathXmlApplicationContext:从类路径获取配置文件。
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml")
• FileSystemXmlApplicationContext:从文件系统获取配置文件。
ApplicationContext context = new FileSystemXmlApplicationContext("c:/application.xml");
ApplicationContext获取bean的方法:
1、通过id获取容器中的bean
1 ApplicationContext context = new ClassPathXmlApplicationContext("application.xml"); 2 HelloWord hello = (HelloWord) context.getBean("helloword");
2、通过类类型获取。但是只能在HelloWord类只有一个bean对象才行,不然就不知道到底获取哪一个而报错
1 ApplicationContext context = new ClassPathXmlApplicationContext("application.xml"); 2 HelloWord hello = context.getBean(HelloWord.class); //不用类型强转,因为已经知道返回类型了
IOC容器注入依赖资源,三种注入方式:
1、属性注入(最常用)
2、构造器注入
3、工厂方法注入(很少用,不推荐)
属性注入:通过setter方法注入;使用<property>,使name属性指定bean的属性名称
<property name="name" value="Spring"></property>
表示bean所在类有一个name属性,值是Spring
构造器注入
用bean里的constructor-arg属性
例子--新建一个Car类
1 public class Car{ 2 private String brand; 3 private String corp; 4 private double price; 5 private int maxSpeed; 6 } 7 public Car(String brand,String corp,double price){ 8 super(); 9 this.brand=brand; 10 this.corp=corp; 11 this.price=price; 12 }
xml中添加,index表示对应的属性,若不写,默认按顺序匹配
1 <bean id="car" class="com.guigu.spring.beans.Car"> 2 <constructor-arg value="aodi" index="0"></constructor-arg> 3 <constructor-arg value="ShangHai" index="1"></constructor-arg> 4 <constructor-arg value="300000" index="2"></constructor-arg> 5 </bean>
main函数中
1 ApplicationContext ctx= new ClassPathXmlApplicationContext("application.xml"); 2 HelloWord car=ctx.getBean(Car.class); 3 system.out.println(car); //调用Car中的toString函数,已省略
输出结果:Car [brand=aodi, corp=ShangHai, price=300000, maxSpeed=0];
若构造函数是多个呢?重载的构造函数,xml中对应哪一个呢?
1 public class Car{ 2 private String brand; 3 private String corp; 4 private double price; 5 private int maxSpeed; 6 } 7 public Car(String brand,String corp,double price){ 8 super(); 9 this.brand=brand; 10 this.corp=corp; 11 this.price=price; 12 } 13 public Car(String brand,String corp,int maxSpeed){ 14 super(); 15 this.brand=brand; 16 this.corp=corp; 17 this.maxSpeed=maxSpeed; 18 }
1 <bean id="car2" class="com.guigu.spring.beans.Car"> 2 <constructor-arg value="aodi" type="java.lang.String"></constructor-arg> //除基本类型外,其余都要写全类名 3 <constructor-arg value="ShangHai" type="java.lang.String"></constructor-arg> 4 <constructor-arg value="240" type="int"></constructor-arg> //基本类型,不用谢全类名 5 </bean>
1 ApplicationContext ctx= new ClassPathXmlApplicationContext("application.xml"); 2 HelloWord car=ctx.getBean("car"); 3 system.out.println(car); 4 HelloWord car=ctx.getBean("car2"); 5 system.out.println(car);
输出结果:
Car [brand=aodi, corp=ShangHai, price=300000.0, maxSpeed=0];
Car [brand=aodi, corp=ShangHai, price=0.0, maxSpeed=240];
总结:通过构造器方法时,可以用参数的位置和参数的类型来区分重载构造函数,位置和参数是可以同时使用,如下
1 <bean id="car" class="com.guigu.spring.beans.Car"> 2 <constructor-arg value="aodi" index="0"></constructor-arg> 3 <constructor-arg value="ShangHai" index="1"></constructor-arg> 4 <constructor-arg value="240" type="int"></constructor-arg> 5 </bean>
细节1:value用节点表示
1 <bean id="car" class="com.guigu.spring.beans.Car"> 2 <constructor-arg value="aodi" index="0"></constructor-arg> 3 <constructor-arg value="ShangHai" index="1"></constructor-arg> 4 <constructor-arg type="int"> 5 <value>240</value> 6 </constructor-arg> 7 </bean>
这个可以解决value是特殊字符的问题 如:<ShangHai> ,直接字面写就报错,用value节点再结合<![CDATA[]]解决
1 <bean id="car" class="com.guigu.spring.beans.Car"> 2 <constructor-arg value="aodi" index="0"></constructor-arg> 3 <constructor-arg index="1"> 4 <value><![CDATA[<ShangHai>]]></value> // 值是:<ShangHai> 5 </constructor-arg> 6 <constructor-arg value="240" type="int"> 7 </constructor-arg> 8 </bean>
细节2:属性是引用类型 ref元素或ref属性
若又一个Person类,有一个Car属性,Car就是前面的对象
1 public class Person{ 2 private String name; 3 private Car car; 4 } 5 6 public void setName(String name){ 7 this.name=name; 8 } 9 public getName(){ 10 return name; 11 } 12 public void setCar(Carcar){ 13 this.car=car; 14 } 15 public getCar(){ 16 return car; 17 } 18 19 }
用ref="car2" 指向之前的car2对象,来引用;同样可以改成节点式<ref bean="car2"/>
1 <bean id="person" class="com.guigu.spring.beans.Person"> 2 <property name="name" value="Tom"></proerty> 3 <property name="car" ref="car2"></proerty> 4 </bean>
细节3:内部bean,达到和引用的目的。但这个bean不能被外部引用,只能自己内部使用
1 <bean id="person" class="com.guigu.spring.beans.Person"> 2 <property name="name" value="Tom"></proerty> 3 <property name="car"> 4 <bean class="com.guigu.spring.beans.Car"> 5 <constructor-arg value="Ford"></constructor-arg> 6 <constructor-arg value="ChangAn"></constructor-arg> 7 <constructor-arg value="200000" type="double"></constructor-arg> 8 </bean> 9 </proerty> 10 </bean>
细节4:赋空值: <null/>;或者,直接不写就行。
1 <bean id="person" class="com.guigu.spring.beans.Person"> 2 <property name="name" value="Tom"></proerty> 3 <property name="car"> 4 <bean class="com.guigu.spring.beans.Car"> 5 <constructor-arg value="Ford"></constructor-arg> 6 <constructor-arg value="ChangAn"></constructor-arg> 7 <constructor-arg><null/></constructor-arg> 8 </bean> 9 </proerty> 10 </bean>
细节5:像struts一样,可以为级联属性赋值。它调用了改属性的set方法,所以类中必须要有改属性的set方法。
1 <bean id="person" class="com.guigu.spring.beans.Person"> 2 <constructor-arg
name
="name" value="Tom"></constructor-arg> 3 <constructor-arg name="car" ref="car2"> 4 <property name="car.maxSpeed" value="230"></property> // 5 </constructor-arg> 6 </bean>
注意:和struts不同,不能不初始化直接赋值
1 <bean id="person" class="com.guigu.spring.beans.Person"> 2 <property name="name" value="Tom"></proerty> 3 <!-- 4 <property name="car"> 5 <bean class="com.guigu.spring.beans.Car"> 6 <constructor-arg value="Ford"></constructor-arg> 7 <constructor-arg value="ChangAn"></constructor-arg> 8 <constructor-arg value="200000" type="double"></constructor-arg> 9 </bean> 10 </proerty> 11 --> 12 <property name="car.maxSpeed" value="260"></property> 13 </bean>
这里的意思是,不创建car对象,直接对它的属性赋值。
在struts中可以,会自动先创建一个car对象,然后赋值。二spring不可以,必须先初始化一个对象,再赋值。
细节6:集合属性赋值
一个person可以有多个car,怎么表示? 如下,用节点<list> 。数组list和Set与集合类似。也可以用内部bean
1 public class Person{ 2 private String name; 3 private List<Car> cars; 4 } 5 6 public void setName(String name){ 7 this.name=name; 8 } 9 public getName(){ 10 return name; 11 } 12 public void setCar(List<Car> cars){ 13 this.cars=cars; 14 } 15 public List<Car> getCars(){ 16 return cars; 17 } 18 19 }
1 <bean id="person1" class="com.guigu.spring.beans.Person"> 2 <constructor-arg name="name" value="Tom"></constructor-arg> 3 <property name="car"> 4 <list> 5 <ref bean="car1"/> 6 <ref bean="car2"/> 7 </list> 8 </property > 9 </bean>
注意:集合中Map又不一样,因为它是键值对,用<map>、entry
1 public class NewPerson{ 2 private String name; 3 private Map<String, Car> cars; 4 5 public String getName(){ 6 return name; 7 } 8 public void setName(){ 9 this.name=name; 10 } 11 public Map<String, Car> getCars(){ 12 return cars; 13 } 14 public void setCars(Map<String, Car> cars) { 15 this.cars=cars; 16 }
1 <bean id="newPerson" class="com.guigu.spring.beans.Person"> 2 <property name="name" value="evan"></property > 3 <property name="cars"> 4 <map> 5 <entry key="AA" value-ref="car"/> 6 <entry key="BB" value-ref="car2"/> 7 </map> 8 </property > 9 </bean>
细节7:配置properties 。 一个DataSource类,xml配置properties。如连接数据库
1 public class DataSource{ 2 private Properties properties; 3 public Properties getProperties(){ 4 return properties; 5 } 6 public void setProperties(Properties properties){ 7 this.properties = properties; 8 }
1 <bean id="dataSource" class="com.guigu.spring.beans.DataSource"> 2 <property name="properties"> 3 <props> 4 <prop key="user">root<prop> 5 <prop key="password">1234<prop> 6 <prop key="jdbcUrl">jdbc:mysql://test<prop> 7 </prop> 8 <properties> 9 </bean>
1 DataSource datasource = ctx.getBean(DataSource.class); 2 System.out.print(datasource.getProperties);
输出:
{user=root, password=1234, jdbcUrl=jdbc://test}
细节8:上面集合的配置,如果多个对象要使用,怎么提高内部属性的利用率<props>、<map>。用一个util命名空间
//单独拿出来,可以供多个bean调用 <util:list id="cars"> <ref bean="car"/> <ref bean="car2"/> </util:list> //引用 <bean id="person3" class="com.guigu.spring.beans.Person"> <property name="name" value="jack"></property > <property name="cars" ref="cars"></property > </bean>