如果看了前面的翻译,相信稍微也可以看出SpringFramework提供的几块功能。单从翻译的角度去学习SpringFramework难免会有些吃力,并且SpringFramework提供的很多模块和配置并不是都要使用的,所以接下来还是以实际的demo和内部实现原理学习一下SpringFramework框架。
本篇文章只展示一下使用spring的效果,不做过多的解释。
1.构建java项目
这里使用的是maven构建java项目(如果对maven不是很了解的,建议先看看博主的maven系列)。
2.添加依赖
pom.xml配置
SpringFramework提供了很多的模块,如果只使用IOC容器,则只需要添加4个包即可。分别是:spring-core,spring-beans,spring-context,spring-expression。
但是spring-core模块需要依赖commons-logging日志jar,所以引入spring-core时需要将commons-logging日志包引入(具体为什么要依赖,请查看SpringFramework官方文档)。也可以选择不使用commons-logging日志作为依赖,使用其他如log4j作为日志实现也可以。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.springframework</groupId>
<artifactId>spring-study-03</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-study-03</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
<!-- <exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions> -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
3.创建一个实体
Employee
package com.springframework.beans;
public class Employee {
private int id;
private String userName;
private String loginName;
private String password;
private int gender;
private String email;
private String phoneNumber;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return "Employee [id=" + id + ", userName=" + userName + ", loginName="
+ loginName + ", password=" + password + ", gender=" + gender
+ ", email=" + email + ", phoneNumber=" + phoneNumber + "]";
}
}
4.创建配置文件
spring-helloworld.xml
配置文件命名空间,直接从官方文档中复制。
配置Employee,设置id为employee,并设置部分的属性值name为Employee属性名,value为属性值。
<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-3.0.xsd">
<!--
配置bean
class: bean 的全类名,通过反射的机制在ioc容器中创建bean,要求必须有一个无参数的构造器
id: 标识容器中的bean,id唯一
-->
<bean id="employee" class="com.springframework.beans.Employee">
<property name="userName" value="张三" />
<property name="loginName" value="zhangsan" />
<property name="email" value="aa@qq.com" />
<property name="phoneNumber" value="18516264211" />
</bean>
</beans>
5.创建测试类
package com.springframework.helloworld;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.springframework.beans.Employee;
public class HelloworldTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring-helloworld.xml"});
Employee emp1 = ac.getBean(Employee.class);
Employee emp2 = (Employee)ac.getBean("employee");
System.out.println("emp1:"+emp1);
System.out.println("emp2:"+emp2);
}
}
结果:
信息: Loading XML bean definitions from class path resource [spring-helloworld.xml]
emp1:Employee [id=0, userName=张三, loginName=zhangsan, password=null, gender=0, email=aa@qq.com, phoneNumber=18516264211]
emp2:Employee [id=0, userName=张三, loginName=zhangsan, password=null, gender=0, email=aa@qq.com, phoneNumber=18516264211]
使用spring之前,如果需要创建一个bean,如Employee类,我们通常的做法是
Employee emp = new Employee();
主动的new创建bean。
使用SpringFramework的IOC容器之后,我们并没有去创建bean,而是通过获取配置文件,然后直接使用getBean()方法就获取到了这个bean的实例。
6.执行过程
为什么直接调用getBean()就可以获取到实例化的bean,且还能获取到各属性的值呢,我们通过打印的形式做一下追踪。
对Employee添加部分打印操作
package com.springframework.beans;
public class Employee {
private int id;
private String userName;
private String loginName;
private String password;
private int gender;
private String email;
private String phoneNumber;
//添加打印
public Employee() {
System.out.println("我是Employee的Constructor");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
//添加打印
public void setUserName(String userName) {
System.out.println("我是setUserName方法:"+userName);
this.userName = userName;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
@Override
public String toString() {
return "Employee [id=" + id + ", userName=" + userName + ", loginName="
+ loginName + ", password=" + password + ", gender=" + gender
+ ", email=" + email + ", phoneNumber=" + phoneNumber + "]";
}
}
修改测试类:
package com.springframework.helloworld;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.springframework.beans.Employee;
public class HelloworldTest {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"spring-helloworld.xml"});
//去掉之后的所有操作,只做获取ClassPathXmlApplicationContext操作。
}
执行结果:
我是Employee的Constructor
我是setUserName方法:张三
结果显示,在执行ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{“spring-helloworld.xml”});操作时,已经实例化并将属性设置给Employee。所以在调用getBean()方法的时候可以直接是从一个类似于容器的BeanFactory中获取到的。