Spring的入门

1. Spring的概述

1.1 什么是Spring?
  • Spring的核心是控制反转(IoC)和面向切面(AOP)。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
1.2 Spring框架的优点
  • 方便解耦,简化开发 (高内聚低耦合)

Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理 ,spring工厂是用于生成bean

  • AOP编程的支持

Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

  • 声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无需手动编程

  • 方便程序的测试

Spring对Junit4支持,可以通过注解方便的测试Spring程序

  • 方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持

  • 降低JavaEE API的使用难度

Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

2. 什么是IOC?
  • IOC:Inversion of Control

控制反转:将对象的创建权反转交给Spring容器,控制权由对象本身转向Spring容器;由Spring容器根据配置文件去创建实例并创建各个实例之间的依赖关系

3. Spring的入门
  • 3.1 spring 官网:

http://spring.io

  • Spring的目录结构与介绍
    在这里插入图片描述
  1. docs : Spring的开发规范和API
  2. libs : Spring的开发的jar包和源码
  3. scheme : Spring的配置文件的约束
  • Spring的项目搭建
  • 导入jar包
    在这里插入图片描述
    导入四个核心jar包即可,需要日志文件的化需要导入日志文件的jar包,不需要的化四个就够了。
    在这里插入图片描述
  • Spring的底层的实现原理
    在这里插入图片描述
  • 编写一个接口类
package spring.demo1;

//用户管理业务层的接口
public interface UserDAO {
	public void save();
}

  • 编写一个实现类
package spring.demo1;

public class UserDAOImpl implements UserDAO {
	@Override
	public void save() {
		System.out.println("UserDAOImpl执行了" );
	}
}

  • 编写Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	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.xsd">
	<!-- Spring的入门配置 -->
	<bean id="userDAO" class="spring.demo1.UserDAOImpl">
	</bean>
</beans>
  • 编写测试类比较传统方式的调用与Spring方式的调用
package spring.demo1;
//Spring 的入门

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDemo1 {
//传统方式的调用,可以输出结果
	@Test
	public void demo1() {
		UserDAOImpl us = new UserDAOImpl();
		us.save();
	}

	// Spring方式的调用,输出同样的结果,通过配置文件去调用
	@Test
	public void demo2() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDAO userDAO = (UserDAO) applicationContext.getBean("userDAO");
		userDAO.save();
	}

}

  • 两者的区别,传统方式的调用如果改变需要修改源代码,而Spring调用的方式只需要修改配置文件中的 配置类的路径即可。

IOC和DI

IOC:控制反转,将对象的创建权反转交给Spring

  • DI:依赖注入,前提是必须有IOC环境,Spring管理这个类的时候将类的依赖属性注入(设置)进来。
package spring.demo1;

public class UserDAOImpl implements UserDAO {

	private String name;

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

	@Override
	public void save() {
		System.out.println("UserDAOImpl DI属性注入" + name);
	}
}

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
	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.xsd">
	<!-- Spring的入门配置 -->
	<bean id="userDAO" class="spring.demo1.UserDAOImpl">
	<!--DI属性注入  -->
	<property name="name" value="haha"></property>
	</bean>
</beans>
package spring.demo1;
//Spring 的入门
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo1 {
	// Spring方式的调用
	@Test
	public void demo2() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDAO userDAO = (UserDAO) applicationContext.getBean("userDAO");
		userDAO.save();
	}
}

4 Spring的工厂类介绍
  • BeanFactory : 老版本的工厂类

在调用getBean的时候,才会生成类的实例

  • ApplicationContext :新版本的工厂类
  1. ApplicationContext :加载配置文件的时候,就会将Spring管理的类都实例化
  2. ApplicationContext有两个实现类
  • ClassPathXmlApplicationContext :加载类路径下的配置文件
  • FileSystemXmlApplicationContext :加载文件系统下的配置文件(硬盘上的文件)
	@Test
	public void demo2() {
	//加载类路径下的配置文件
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDAO userDAO = (UserDAO) applicationContext.getBean("userDAO");
		userDAO.save();
	}

	@Test
	public void demo3() {
	//加载文件系统下的配置文件(硬盘上的配置文件)
		ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:\\applicationContext.xml");
		UserDAO userDAO = (UserDAO) applicationContext.getBean("userDAO");
		userDAO.save();
	}

  • ApplicationContext和BeanFactory的区别?
  • Spring的工厂类结构图
    在这里插入图片描述

5. Spring的配置文件的各类属性

5.1 Bean标签的相关属性详解
  • id : 使用约束中的唯一约束,里面不能出现特殊字符
  • name : 没有使用约束中的唯一约束(理论上是可以出现重复的,但是实际开发不会出现),里面可以出现特殊字符
  • class : 需要被Spring管理的类的全路径
5.2 Bean 的生命周期的配置(了解)
  • 1.编写实类
package spring.demo2;

public class CustomerDAOImpl implements CustomerDAO {
//此处省略CustomerDAO的编写,和入门案例一样的
	public void setup() {
		System.out.println("CustomerDAOImpl被初始化了。。");
	}

	@Override
	public void save() {
		System.out.println("CustomerDAOImpl的save方法执行了。。");
	}

	public void destroy() {
		System.out.println("CustomerDAOImpl的destroy销毁了。。");
	}
}

  • 编写配置文件,重点在这里,看配置文件的各个属性
<bean id="customerDAO"
	class="com.itheima.spring.demo2.CustomerDAOImpl"
	init-method="setup" destroy-method="destroy">
</bean>
  • 生命周期的测试类
@Test
public void demo1() {
	// 用第一个不能执行销毁的方法
	// ApplicationContext applicationContext = new
	// ClassPathXmlApplicationContext("applicationContext.xml");
	ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	CustomerDAO customerDAO = (CustomerDAO) applicationContext.getBean("customerDAO");
	customerDAO.save();
	applicationContext.close();
}

  • init-method :Bean被初始化的时候执行的方法
  • destroy-method : Bean被销毁的时候执行的方法
5.3 Bean的作用范围的配置(重点)

scope 属性:Bean的作用范围

  • singleton :默认的,单例模式创建这个(new一次,用多次)

  • prototype :多例模式(用一次就new一个)

  • request : 应用在web项目中,Spring创建这个类以后,将这个类存入request作用域

  • session :应用在web项目中,Spring创建这个类以后,将这个类存入session作用域

  • globalsession : 应用在web项目,必须在porlet环境下使用

  • 案例

<!--Bean的作用范围的配置,默认情况是单例的,scope="singleton"  -->
<bean id="customerDAO"
	class="com.itheima.spring.demo2.CustomerDAOImpl"
	init-method="setup" destroy-method="destroy">
</bean>
  • 单例(默认)测试类
@Test
public void demo2() {
	ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	CustomerDAO customerDAO1 = (CustomerDAO) applicationContext.getBean("customerDAO");
	System.out.println(customerDAO1);
	CustomerDAO customerDAO2 = (CustomerDAO) applicationContext.getBean("customerDAO");
	System.out.println(customerDAO2);
	System.out.println(customerDAO1 == customerDAO2);
	applicationContext.close();

结果是true ,两次new创建出来的实例是一样的

  • 多例模式,想一下?需要在配置文件中配置scope=“prototype” ,再次运行测试类,会发现两次创建的是不一样的实例。

6. Spring的属性注入

在这里插入图片描述

6.1.构造方法的方式属性的注入
  • 编写构造方法类
package spring.demo4;

public class Car {
private String name;
private Double price;

public Car(String name, Double price) {
	super();
	this.name = name;
	this.price = price;
}

@Override
public String toString() {
	return "Car [name=" + name + ", price=" + price + "]";
}
}

  • 配置
<bean id="car" class="spring.demo4.Car">
<constructor-arg name="name" value="宝马"></constructor-arg>
<constructor-arg name="price" value="808080"></constructor-arg>
</bean>
  • 编写测试类
@Test
//构造方法的属性注入
public void demo1() {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Car car = (Car) applicationContext.getBean("car");
	System.out.println(car);

6.2. set方式的属性注入
  • set方法类的编写
package spring.demo4;

public class Car2 {
private String name;
private Double price;

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

public void setPrice(Double price) {
	this.price = price;
}

@Override
public String toString() {
	return "Car2 [name=" + name + ", price=" + price + "]";
}
}

  • 配置
<!-- set方法的属性注入方式 -->
<bean id="car2" class="spring.demo4.Car2">
<property name="name" value="奥迪"></property>
<property name="price" value="1000000"></property>
</bean>
  • 测试方法
@Test
//set方法的属性注入
public void demo2() {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Car2 car2 = (Car2) applicationContext.getBean("car2");
	System.out.println(car2);

6.2.2 set方法设置对象类型的属性注入
package spring.demo4;

public class Employee {
private String name;
private Car2 car2;

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

public void setCar2(Car2 car2) {
	this.car2 = car2;
}

@Override
public String toString() {
	return "Employee [name=" + name + ", car2=" + car2 + "]";
}
}

  • 配置文件(重要注释)
<!--set方法注入对象类型的属性 -->
<bean id="employee" class="spring.demo4.Employee">
	<!--value:设置普通类型的值,ref:设置其他的类的id或name -->
	<property name="name" value="xiabaobao"></property>
	<property name="car2" ref="car2"></property>
</bean>
  • 测试方法
@Test
public void demo3() {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Employee employee = (Employee) applicationContext.getBean("employee");
	System.out.println(employee);
}
6.3 P 名称空间的属性注入
  • 通过引入P名称空间完成属性的注入
  • 写法

普通属性 P:属性名=“值“
对象属性 P :属性名-ref=“值”

  • 第一步: p的设置
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:p="http://www.springframework.org/schema/p"
  • 第二,注入普通类型的属性
<bean id="car2" class="spring.demo4.Car2" p:name="奔驰"
	p:price="300000"></bean>
  • 测试
public void demo2() {
	ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	Car2 car2 = (Car2) applicationContext.getBean("car2");
	System.out.println(car2);
}
  • 假如注入对象类型的属性
<bean id="employee" class="spring.demo4.Employee"
p:name="xiabaobao" p:car2-ref="car2"></bean>
6.4 SpEL的属性注入

看文档吧

6.5 复杂(集合)属性的注入

猜你喜欢

转载自blog.csdn.net/xiayubao7788/article/details/88806893