概念

Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。

Spring的初衷:

1、JAVA EE开发应该更加简单。

2、使用接口而不是使用类,是更好的编程习惯。Spring将使用接口的复杂度几乎降低到了零。

3、为JavaBean提供了一个更好的应用配置框架。

4、更多地强调面向对象的设计,而不是现行的技术如JAVA EE。

5、尽量减少不必要的异常捕捉。

6、使应用程序更加容易测试。

Spring的目标:

1、可以令人方便愉快的使用Spring。

2、应用程序代码并不依赖于Spring APIs。

3、Spring不和现有的解决方案竞争,而是致力于将它们融合在一起。

Spring的基本组成:

1、最完善的轻量级核心框架。

2、通用的事务管理抽象层。

3、JDBC抽象层。

4、集成了Toplink, Hibernate, JDO, and iBATIS SQL Maps。

5、AOP功能。

6、灵活的MVC Web应用框架。

1.项目环境搭建

打开idea开发软件,新建web application项目,在WEB-INF下新建lib文件夹,将以下jar包导入其中

spring 开源框架 spring框架的搭建和开发_spring

这些jar包中用于Spring框架的使用和JUnit的单元测试。

 将Spring框架的主配置文件导入resources资源文件夹中,并转换成项目的资源文件夹

spring 开源框架 spring框架的搭建和开发_aop_02

 如果该过程未掌握的初学者,请先阅读【MyBatis】第一课 MyBatis的框架的搭建和使用

该文中有详细的步骤进行关联jar以及转换资源文件夹。

2.创建实体类以及测试类

在src文件夹中,创建com.spring.entity和com.spring.test包,分别在包中创建Student实体类和SpringTest测试类。

其Student.java中代码如下:

package com.spring.entity;

import java.util.Date;

public class Student {
    private String name;
    private int age;
    private Date birthday;

    public Student() {
    }

    public Student(String name, int age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

在SpringTest类中创建测试类方法,通过java代码方式创建对象以及Spring框架方式创建对象进行对比。

java代码创建对象以及赋值全局变量的方式:

@Test
    public void one(){
        //java的面向对象
        Student student1=new Student();
        student1.setName("小明");
        student1.setAge(20);
        System.out.println(student1);
        System.out.println(student1.getName()+"--"+student1.getAge());
        

    }

Spring框架使用xml方式创建对象,在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-4.0.xsd">

	<!--Student student1=new Student();-->
	<!--scope=""用于设置当前对象在被创建的时候,使用一个对象还是多个对象
	singleton:创建多个对象的时候,只使用一个对象   单例模式    默认为单例模式
	prototype:创建多个对象       多例模式-->
	<bean id="stu" class="com.spring.entity.Student" >
		<property name="name" value="小王"></property>
		<property name="age" value="22"></property>
	</bean>

	


	

</beans>

接着在测试类中定义方法进行获得主配置文件中创建的对象:

//使用Spring框架的方式将对象写入了xml文件中
        //首先需要加载Spring框架的主配置文件
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        //Spring框架创建多个对象,默认是单例模式,只有一个对象。
        Student stu=(Student) ac.getBean("stu");
        System.out.println(stu);
        System.out.println(stu.getName()+"--"+stu.getAge());

那么如果全局变量中包含引用数据类型的实体类变量,那么需要进行单独创建出来,然后使用ref属性进行关联。

@Test
    public void two(){
        //java代码方式
        Student student=new Student();
        student.setName("徐树华");
        student.setAge(17);
        Date date=new Date();
        date.setYear(120);
        date.setMonth(12);
        date.setDate(20);
        System.out.println(date);
        student.setBirthday(date);

       
    }

而使用Spring框架方式需要在ApplicationContext.xml文件中:

<bean id="stu" class="com.spring.entity.Student" >
		<property name="name" value="小王"></property>
		<property name="age" value="22"></property>
		<property name="birthday" ref="date"></property>
	</bean>

	<!--Date date=new Date();-->
	<bean id="date" class="java.util.Date">
		<property name="year" value="121"></property>
		<property name="month" value="3"></property>
		<property name="date" value="28"></property>
	</bean>

并使用测试方法进行获得:

//Spring框架方式
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student1=ac.getBean("stu",Student.class);
        System.out.println(student1.getName()+"--"+student1.getAge()+"--"+student1.getBirthday());

3.通过构造方法赋值全局变量

java代码方式同构构造方法进行赋值:

@Test
    public void five(){
        Date birthday=new Date();
        Student student=new Student("小明",20,birthday);
        System.out.println(student.getName()+"--"+student.getAge()+"--"+student.getBirthday());

        

    }

Spring框架的主配置文件中赋值:

<!--Date birthday=new Date();-->
	<bean id="birthday" class="java.util.Date"></bean>
	<!--Student student=new Student("小明",20,birthday);-->
	<bean id="ss" class="com.spring.entity.Student">
		<!--等价于构造方法的写法
		constructor-arg:该标签表示构造方法
			type:该属性表示根据变量的数据类型进行赋值(不建议使用,当类中出现多个相同数据类型的变量,不利于区分变量)
			index:该属性表示根据构造方法中参数的下标来赋值
			name:该属性表示根据全局变量名称来赋值,常用这种方式来进行赋值
			value:用于给基本数据类型赋值
			ref:用于给引用数据类型赋值
		-->
		<constructor-arg type="java.lang.String"  value="小王"></constructor-arg>
		<constructor-arg index="1"  value="20"></constructor-arg>
		<constructor-arg name="birthday" ref="birthday"></constructor-arg>
	</bean>

在测试方法中获得:

ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student ss=ac.getBean("ss",Student.class);
        System.out.println(ss.getName()+"@@"+ss.getAge()+"@@"+ss.getBirthday());

4.间接创建对象的方式

定义一个School类,中通过方法创建Student类的对象,其中一个是成员方法,一个是静态方法

package com.spring.entity;

public class School {

    public Student getStudent(){
        return new Student();
    }

    public static Student getStudent1(){
        return new Student();
    }

}

在测试类中测试获得对象:

@Test
    public void three(){
//获得成员方式
        School school=new School();
        Student student = school.getStudent();
        System.out.println(student);


        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student1=ac.getBean("student",Student.class);
        System.out.println(student1.getName()+"--"+student1.getAge());
    }

    @Test
    public void four(){
//获得静态方法
        Student student = School.getStudent1();

        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student1=ac.getBean("s",Student.class);
        System.out.println(student1.getName()+"--"+student1.getAge());
    }

使用Spring框架中通过调用成员方法和静态方法获得Student对象

<!--第二种间接获得对象的方式-->
	<!--School school=new School();-->
	<bean id="school" class="com.spring.entity.School"></bean>
	<!--Student student = school.getStudent();-->
	<bean id="student" factory-bean="school" factory-method="getStudent">
		<property name="name" value="马云"></property>
		<property name="age" value="50"></property>
	</bean>

	<!--第三种间接获得对象的方式-->
	<!-- Student s = School.getStudent1();-->
	<bean id="s" class="com.spring.entity.School"  factory-method="getStudent1">
		<property name="name" value="任正非"></property>
		<property name="age" value="80"></property>
	</bean>

5.通过Spring框架给数组,集合,Map集合进行赋值

创建一个实体类,定义各种存储大量数据的数组,集合类型的全局变量

package com.spring.entity;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Car {
    private String[] types;//汽车的品牌,宝马,奔驰,奥迪。。。
    private List<Integer> prices;//汽车的价格:  100万   10万
    private Map<String,String> colors;//汽车的颜色
    private Set<String> utils;//交通工具: 自行车,货车,火车,飞机
    private Properties properties;

    public String[] getTypes() {
        return types;
    }

    public void setTypes(String[] types) {
        this.types = types;
    }

    public List<Integer> getPrices() {
        return prices;
    }

    public void setPrices(List<Integer> prices) {
        this.prices = prices;
    }

    public Map<String, String> getColors() {
        return colors;
    }

    public void setColors(Map<String, String> colors) {
        this.colors = colors;
    }

    public Set<String> getUtils() {
        return utils;
    }

    public void setUtils(Set<String> utils) {
        this.utils = utils;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

使用java代码方式对这些全局变量赋值的代码如下:

@Test
    public void six(){
        Car car=new Car();
        String[] strs={"劳斯莱斯","红旗","比亚迪"};
        car.setTypes(strs);
        System.out.println(Arrays.toString(car.getTypes()));

        List<Integer> ps=new ArrayList<>();
        ps.add(100);
        ps.add(20);
        ps.add(50);
        car.setPrices(ps);
        car.getPrices().forEach(price-> System.out.println(price));

        Map<String,String> m=new HashMap<>();
        m.put("red","红色");
        m.put("yellow","黄色");
        m.put("blue","蓝色");
        car.setColors(m);
        car.getColors().forEach((k,v)-> System.out.println(k+":"+v));

        Set<String> set=new HashSet<>();
        set.add("自行车");
        set.add("火车");
        set.add("飞机");
        car.setUtils(set);
        car.getUtils().forEach(s-> System.out.println(s));

        //存储连接数据库的四个参数
        Properties properties=new Properties();
        //驱动程序
        properties.setProperty("Driver","com.mysql.cj.jdbc.Driver");
        //访问数据库的地址
        properties.setProperty("url","jdbc:mysql://localhost:3306/car");
        //登录数据库的用户名
        properties.setProperty("username","root");
        //登录数据库的密码
        properties.setProperty("password","123456");
        car.setProperties(properties);
        car.getProperties().forEach((k,v)-> System.out.println(k+":"+v));

       
    }

使用Spring框架的方式,主配置文件中:

<!--Car car=new Car();-->
	<bean id="car" class="com.spring.entity.Car">
		<property name="types">
			<array>
				<value>宝马</value>
				<value>奔驰</value>
				<value>奥迪</value>
			</array>
		</property>

		<property name="prices">
			<list>
				<value>40</value>
				<value>60</value>
				<value>80</value>
			</list>
		</property>

		<property name="utils">
			<set>
				<value>货车</value>
				<value>拖拉机</value>
				<value>火箭</value>
			</set>
		</property>

		<property name="colors">
			<map>
				<entry key="white"  value="白色"></entry>
				<entry key="black" value="黑色"></entry>
				<entry key="pink" value="粉色"></entry>
			</map>
		</property>

		<property name="properties">
			<props>
				<prop key="Driver">com.mysql.cj.jdbc.Driver</prop>
				<prop key="url">jdbc:mysql://localhost:3306/car</prop>
				<prop key="username">root</prop>
				<prop key="password">123456</prop>
			</props>
		</property>
	</bean>

在测试方法中测试的运行代码如下: 

ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car1 = ac.getBean("car", Car.class);
        System.out.println(Arrays.toString(car1.getTypes()));
        car1.getPrices().forEach(p-> System.out.println(p));
        car1.getColors().forEach((k,v)-> System.out.println(k+"!"+v));
        car1.getUtils().forEach(s-> System.out.println(s));
        car1.getProperties().forEach((k,v)-> System.out.println(k+":"+v));

6.使用Spring框架建立类的生命周期

定义一个类,在类中建立需要执行的几个方法

package com.spring.entity;

public class Dog {

	public Dog(){
		System.out.println("创建对象");
	}

    //用于初始化数据的方法
    public void init(){
        System.out.println("小狗出生了");
    }

    //用于正在运行
    public void service(){
        System.out.println("小狗正在一天天长大");
    }

    //销毁当前对象
    public void destroy(){
        System.out.println("小狗生命走到了终点");
    }
}

在xml主配置文件中:

<!--指定某个类在创建对象的时候,先执行什么,后执行什么-->
	<bean id="dog" class="com.spring.entity.Dog"
		  init-method="init" destroy-method="destroy"></bean>

单元测试的方法中执行代码:

@Test
    public void seven(){
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
        Dog dog = ac.getBean("dog", Dog.class);
        dog.service();

        //任务处理完了,需要关闭,释放所有对象的内存
        ((ClassPathXmlApplicationContext) ac).close();
    }

通过运行可以观察到dog对象已被创建就执行了构造方法和init方法,在主配置文件关闭的时候执行了destroy方法。

总结

Spring框架是java学习过程中以及java开发中起到至关重要的框架.