一、HelloWorld
需要的jar文件(以2.5.5为例):spring.jar,common-logging.jar
1.新建类com.kdyzm.spring.helloworld.HelloWorld.java
package com.kdyzm.spring.helloworld; public class HelloWorld {
public void say(){
System.out.println("Hello,World!");
}
}
HelloWorld
2.新建配置文件com.kdyzm.spring.helloworld.applicationContext.xml
<?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">
<!-- 注册HelloWorld -->
<bean id="helloWorld" class="com.kdyzm.spring.helloworld.HelloWorld"></bean>
</beans>
com.kdyzm.spring.helloworld.applicationContext.xml
beans标签:对应着spring容器。
bean标签:对应着一个类,id是唯一标识符,class是类路径。
3.新建测试文件HelloWorld.spring.HelloWorldTest.java
package com.kdyzm.spring.helloworld; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class HelloWorldTest {
public static void main(String[] args) {
//测试HelloWorld
ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/helloworld/applicationContext.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorld");
helloWorld.say();
}
}
com.kdyzm.spring.helloworld.HelloWorldTest.java
4.运行结果:
Hello,World!
二、别名
在beans标签下,使用alias标签为bean指定别名,指定别名的好处就是在不同的模块下使用不同的名字,增强可读性。
<bean id="helloWorld" class="com.kdyzm.spring.helloworld.HelloWorld"></bean>
<alias name="helloWorld" alias="狗蛋"/>
<alias name="helloWorld" alias="张三"/>
测试:
ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/helloworld/applicationContext.xml");
HelloWorld helloWorld=(HelloWorld) context.getBean("狗蛋");
helloWorld.say();
三、spring创建对象
1.spring默认在启动spring容器的时候见所有bean都提前进行实例化。提前实例化意味着作为初始化的一部分,ApplicationContext会自动创建并且配置所有的singleton bean。通常情况下这是件好事,因为这样在配置中在有任何错误能够立即发现。
使用lazy-init="true"属性能够开启懒加载,这样初始化bean的时候的时机就变为在调用类中方法的时候。默认为false,禁用懒加载。
2.使用静态工厂方法创建对象
(1)首先创建一个工厂类com.kdyzm.spring.helloworld.HelloWorldFactory.java
package com.kdyzm.spring.helloworld;
/*
* 静态工厂类
*/
public class HelloWorldFactory {
public static HelloWorld getInstance(){
return new HelloWorld();
}
}
com.kdyzm.spring.helloworld.HelloWorldFactory.java
(2)在com.kdyzm.spring.helloworld.applicationContext.xml配置文件中配置
<bean id="helloWorldFactory" class="com.kdyzm.spring.helloworld.HelloWorldFactory" factory-method="getInstance"></bean>
使用factory-method属性声明使用工厂里的那个方法生成目标对象
(3)测试
ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/helloworld/applicationContext.xml");
HelloWorld helloWorld=(HelloWorld) context.getBean("helloWorldFactory");
helloWorld.say();
直接使用getBean方法获取HelloWorld对象即可。
3.默认情况下使用spring创建对象是单例模式,这种方式创建独享非常容易出现安全性问题。使用bean标签的scope属性解决该问题。
* singleton:默认的方式,单例,属性共享(一般情况下应当将数据放到方法的变量中)
* prototype:多例,当一个bean是多例模式的情况下,lazy-init为false或者default无效,也就是说懒加载强制开启。
配置示例:
<bean id="helloWorld" class="com.kdyzm.spring.scope.HelloWorld" scope="prototype"></bean>
一旦使用多例模式,创建的每个对象在内存中都是独一无二的。
4.指定Bean的初始化方法和销毁方法。
spring在初始化bean或者销毁bean的时候有时候需要做一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法。
applicationContext.xml配置:
<bean id="helloWorld"
class="com.kdyzm.spring.createObject.HelloWorld"
init-method="init"
destroy-method="destroy"
>
</bean>
HelloWorld配置:
package com.kdyzm.spring.createObject; public class HelloWorld {
public void init(){
System.out.println("初始化方法被调用!");
}
public HelloWorld() {
System.out.println("构造方法被调用!");
}
public void say(){
System.out.println("HelloWorld!");
}
public void destroy(){
System.out.println("销毁方法被调用!");
}
}
com.kdyzm.spring.createObject.HelloWorld.java
测试方法:
ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/createObject/applicationContext.xml");
System.out.println("spring容器已经启动!");
HelloWorld helloWorld=(HelloWorld) context.getBean("helloWorld");
helloWorld.say();
ClassPathXmlApplicationContext applicationContext=(ClassPathXmlApplicationContext)context;
applicationContext.close();
将ApplicationContext的引用对象转换成ClassPathXmlApplicationContext对象,调用close方法之后对象才会调用destroy方法。
总结:
* init-method:该方法被spring容器执行,在构造方法之后执行,如果需要在构造方法之后,调用方法之前做一些工作,可以在init方法中完成。
* destroy-method:
如果该bean是单例的,则在spring容器关闭或者销毁的时候,执行该方法
如果该bean是多例的,则spring容器不负责销毁。
所以,要想让spring容器控制住bean的生命周期,那么该bean必须是单例的;如果该bean是多例的,那么关闭资源的操作应当由程序员完成。
四、依赖注入(DI)
什么是依赖注入:当使用spring创建对象的同时给对象中的属性赋初值。
1.使用构造器注入
(1)可以通过参数的顺序依次确定给其赋初值
<constructor-arg index="0">
<value>张三</value>
</constructor-arg>
<constructor-arg index="1">
<value>56</value>
</constructor-arg>
(2)可以通过参数的类型给其赋初值
<constructor-arg type="java.lang.Integer">
<value>56</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
<value>张三</value>
</constructor-arg>
(3)可以根据参数的顺序和类型共同确定某个属性
<bean id="person" class="com.kdyzm.spring.di.Person">
<constructor-arg index="0" type="java.lang.String" value="小强"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" value="12110501001"></constructor-arg>
</bean>
测试(3):
package com.kdyzm.spring.di; public class HelloWorld {
private String name;
private Person p; public HelloWorld(String name, Person p) {
this.name = name;
this.p = p;
}
public HelloWorld() {
System.out.println("HelloWorld对象被创建!");
}
public void say() {
System.out.println(name+":"+p);
}
}
com.kdyzm.spring.di.HelloWorld.java
package com.kdyzm.spring.di; public class Person {
private String name;
private String id;
public Person(String name, String id) {
this.name = name;
this.id = id;
}
public Person() {
}
@Override
public String toString() {
return "Person [name=" + name + ", id=" + id + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
com.kdyzm.spring.di.Person.java
测试代码:
ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/di/applicationContext.xml");
HelloWorld helloWorld=(HelloWorld) context.getBean("helloWorld");
helloWorld.say();
运行结果:
狗蛋:Person [name=小强, id=12110501001]
2.使用setting方法进行注入(推荐使用的方法)
(1)简单的数据类型:包装类型和String
<bean id="personService" class="com.itcast.bean.impl.PersonServiceImpl">
<!-- 基本类型,string类型 -->
<property name="age" value="20"></property>
<property name="name" value="张无忌"></property> </bean>
(2)引用其它bean
<bean id="person" class="com.itcast.bean.Person" />
<bean id="personService" class="com.itcast.bean.impl.PersonServiceImpl">
<property name="person" ref="person" />
</bean>
(3)装配List集合。
<property name="lists">
<list>
<value>list1</value>
<value>list2</value>
<ref bean="student"/>
</list>
</property>
(4)装配Set集合
<property name="sets">
<set>
<value>set1</value>
<value>set2</value>
<ref bean="student"/>
</set>
</property>
(5)装配Map
<property name="maps">
<map>
<entry key="01">
<value>map01</value>
</entry>
<entry key="02">
<value>map02</value>
</entry>
</map>
</property>
(6)装配Properties
<property name="props">
<props>
<prop key="01">prop1</prop>
<prop key="02">prop2</prop>
</props>
</property>
(7)小练习:
package com.kdyzm.spring.di.setting; import java.util.List;
import java.util.Map;
import java.util.Set; public class Person {
private String name;
private Integer num;
private Student student;
private List<Student>list;
private Set<Student>set;
private Map<String,Student>map;
public Person() {
System.out.println("Person对象被创建!");
}
public void setName(String name) {
this.name = name;
}
public void setNum(Integer num) {
this.num = num;
}
public void setStudent(Student student) {
this.student = student;
}
public void setList(List<Student> list) {
this.list = list;
}
public void setSet(Set<Student> set) {
this.set = set;
}
public void setMap(Map<String, Student> map) {
this.map = map;
}
@Override
public String toString() {
return "Person [name=" + name + ", num=" + num + ", student=" + student
+ ", list=" + list + ", set=" + set + ", map=" + map + "]";
}
}
com.kdyzm.spring.di.setting.Person.java
package com.kdyzm.spring.di.setting; public class Student {
private String id;
private String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public Student() {
System.out.println("Student对象被创建!");
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
com.kdyzm.spring.di.setting.Student.java
<?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="person" class="com.kdyzm.spring.di.setting.Person">
<property name="name" value="小黄"></property>
<property name="num" value="123456"></property>
<property name="student" ref="student"></property>
<property name="list">
<list>
<ref bean="student"/>
<ref bean="student"/>
</list>
</property>
<property name="set">
<set>
<ref bean="student"/>
<ref bean="student"/>
</set>
</property>
<property name="map">
<map>
<entry key="张三" value-ref="student"></entry>
<entry key="李四" value-ref="student"></entry>
<entry key="王五" value-ref="student"></entry>
</map>
</property>
</bean>
<bean id="student" class="com.kdyzm.spring.di.setting.Student">
<property name="id" value="1"></property>
<property name="name" value="小强"></property>
</bean>
</beans>
com.kdyzm.spring.di.setting.applicationContext.xml
测试代码:
ApplicationContext context=new ClassPathXmlApplicationContext("com/kdyzm/spring/di/setting/applicationContext.xml");
Person person=(Person) context.getBean("person");
System.out.println(person);
运行结果:
Person对象被创建!
Student对象被创建!
Person [name=小黄, num=123456, student=Student [id=1, name=小强], list=[Student [id=1, name=小强], Student [id=1, name=小强]], set=[Student [id=1, name=小强]], map={张三=Student [id=1, name=小强], 李四=Student [id=1, name=小强], 王五=Student [id=1, name=小强]}]