一、Spring简介——什么是Spring?

Spring是分层的JavaSE/EE full-stack 轻量级开源框架,以IoC(Inverse of Control控制反转)和AOP(Aspect Oriented Programming 面向切面编程)为内核,使用基本的JavaBean来完成以前只可能由EJB完成的工作,取代了EJB的臃肿、低效的开发模式。

在实际开发中,通常在服务器端采用三层体系架构,分别为表示层(Web)、业务逻辑层(Service)、持久层(Dao), Spring对每一层都提供了技术支持。

java spring入门示例 java的spring_spring


java spring入门示例 java的spring_tomcat_02

1.1、Spring的体系结构

java spring入门示例 java的spring_spring_03

1.2、Spring框架的优点

Spring具有简单、可测试和松耦合等特点。Spring不仅可以用于服务器端开发,也可以应用于任何Java应用的开发中。

java spring入门示例 java的spring_java_04

二、Spring开发环境配置

说明:不知道需要哪个,所以都安装了

java spring入门示例 java的spring_apache_05

三、Spring HelloWorld(测试环境配置是否成功)

新建动态web工程
导入jar包
编写HelloService及HelloServiceImpl
在classpath创建applicationContext.xml
配置Bean
测试

3.1、新建动态web工程,导入jar包,编写HelloService及HelloServiceImpl

java spring入门示例 java的spring_spring_06


java spring入门示例 java的spring_tomcat_07

3.2、在classpath(src目录)下创建applicationContext.xml

java spring入门示例 java的spring_tomcat_08


java spring入门示例 java的spring_java spring入门示例_09

3.3、在applicationContext.xml中配置Bean

<?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.xsd">
	<!-- 创建com.dgut.spring.hello.HelloServiceImpl类的一个实例对象,即bean,id为helloImpl -->
	<bean id="helloImpl" class="com.dgut.spring.hello.HelloServiceImpl">
	</bean>
</beans>

3.4、使用junit测试

java spring入门示例 java的spring_apache_10


java spring入门示例 java的spring_tomcat_11


全局定义:private ApplicationContext context;

java spring入门示例 java的spring_apache_12


总结:

1、创建接口和接口的实现类

2、在配置文件中创建接口实现类的bean

3、解析配置文件

4、获取接口bean,创建接口实例对象

5、实例对象调用相关接口执行对应功能

3.5、结果

java spring入门示例 java的spring_java spring入门示例_13

四、web环境下的HelloWorld(在Spring HelloWorld(测试环境配置是否成功)的基础上)

4.1、导入jar包

java spring入门示例 java的spring_java_14

4.2、配置web.xml(ALT+/快速操作)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
	  <display-name>spring001</display-name>
	  <!-- 配置使web项目一启动就去找applicationContext.xml配置文件 解决第一次访问慢的问题-->
	  <context-param>
	      <param-name>contextConfigLocation</param-name>
	      <param-value>classpath:applicationContext.xml</param-value>
	  </context-param>
		
	  <!-- 监听器,tomcat服务启动的时候,自动加载spring的核心容器 -->
	  <listener>
	      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	  </listener>
  
</web-app>

4.3、新建serlevt

java spring入门示例 java的spring_java_15

4.4、新建jsp

java spring入门示例 java的spring_java_16


总结:

1、创建接口和接口的实现类

2、在配置文件中创建接口实现类的bean

3、配置使web项目一启动就去找applicationContext.xml配置文件 解决第一次访问慢的问题

4、配置监听器,tomcat服务启动的时候,自动加载spring的核心容器

5、获取servletContext对象和WebApplicationContext对象

6、获取接口bean,创建接口实例对象

7、实例对象调用相关接口执行对应功能

4.5、结果

java spring入门示例 java的spring_spring_17

五、IOC控制反转和DI依赖注入(以下部分未涉及web,即没有配置wen.xml ,使用的是junit测试)

IOC底层原理
xml解析,工厂模式,反射

5.1、依赖注入的概念

DI的全称是Dependency Injection,中文称之为依赖注入。它与控制反转(IOC)的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。

java spring入门示例 java的spring_java spring入门示例_18

5.2、依赖注入的2种方式(其实有三种,第三种在9.1节)

1、在Spring中实现IoC容器的方法是依赖注入,依赖注入的作用是在使用Spring框架创建对象时,动态地将其所依赖的对象(如属性值)注入Bean组件中。

java spring入门示例 java的spring_java_19


2、Bean的属性由方法决定

3、使用构造器注入时,可以用index确定参数的顺序。index从0开始

4、Spring容器加载Bean的时机(容器创建的时候就已经加载好了)

5、使用value子标签<![CDATA[]]>处理特殊属性值。

6、引用其他Bean及内部Bean

7、Bean的属性为集合类型:Array, List, Set, Map

8、集合Bean

5.2.1、实例

java spring入门示例 java的spring_apache_20

Author.java

package com.dgut.spring.di;
import java.util.List;

public class Author {
	private String name;
	private Integer age;
	private List<String> interests;

	public List<String> getInterests() {
		return interests;
	}

	public void setInterests(List<String> interests) {
		this.interests = interests;
	}

	public Author() {
		super();
	}

	public Author(String name, Integer age, List<String> interests) {
		super();
		this.name = name;
		this.age = age;
		this.interests = interests;
	}

	public String getName() {
		return name;
	}

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

	public Integer getAge() {
		return age;
	}

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

	@Override
	public String toString() {
		return "Author [name=" + name + ", age=" + age + ", interests=" + interests + "]";
	}

}

Book.java

package com.dgut.spring.di;

public class Book {
	private String isbn;// 成员变量
	private String name;
	private String price;
	private Author author;

	public Book(String isbn, String name, String price, Author author) {
		super();
		this.isbn = isbn;
		this.name = name;
		this.price = price;
		this.author = author;
	}

	public Author getAuthor() {
		return author;
	}

	public void setAuthor(Author author) {
		this.author = author;
	}

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

	// bean的属性由get和set方法决定,而不是成员变量名决定
	public String getIsbn() {
		return isbn;
	}

	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}

	public String getName() {
		return name;
	}

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

	public String getPrice() {
		return price;
	}

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

	public Book() {
		super();
	}

}

bean的属性用方法决定,不是用成员变量决定
spring-di.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"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<!--====================================================-->
	<!-- 1、用<property>标签 相当于使用setter方法注入方式,调用bean中的set方法注入属性的值 -->
	<bean id="book" class="com.dgut.spring.di.Book">
		<!-- 给bean的属性设置值 -->
		<property name="isbn" value="0001"></property>
		<property name="name">
			<!-- 5、使用value子标签处理特殊字符 -->
			<value><![CDATA[1+1<2?]]></value>
		</property>
		<property name="price" value="58.5"></property>
		<!-- 6、引用其他Bean及内部Bean ,使用ref引用下面的author资源 -->
		<property name="author" ref="author"></property>
		<!-- 使用内部类直接设置bean的属性值
		<property name="author">
			<bean id="author" class="com.dgut.spring.di.Author">
				 给bean的属性设置值
				<property name="name" value="王二毛"></property>
				<property name="age" value="18"></property>
			</bean>
		</property>-->
	</bean>
<!--====================================================-->
	<bean id="author" class="com.dgut.spring.di.Author">
		<!-- 给bean的属性设置值 -->
		<property name="name" value="王二毛"></property>
		<property name="age" value="18"></property>
		<property name="interests" ref="interestsList">
			<!-- 7、Bean的属性为集合类型:Array使用<array>, List使用<list>, Set使用<set>, Map使用<map> -->
			<!-- <list>
				<value>Reading</value>
				<value>Wrting</value>
			</list> -->
		</property>
	</bean>
<!--====================================================-->
	<!-- 8、集合Bean 要引进util,参考本小节附加内容-->
	<util:list id="interestsList">
		<value>Reading</value>
		<value>Swimming</value>
	</util:list>
<!--====================================================-->	
	<!-- 2、使用构造方法注入方式,调用bean中带参的构造器进行属性注入 -->
	<bean id="book1" class="com.dgut.spring.di.Book">
		<!-- 给bean的属性设置值,3、使用index保证和构造器的参数顺序一致 -->
		<constructor-arg value="0002" index="0"></constructor-arg>
		<constructor-arg value="58.5" index="2"></constructor-arg>
		<constructor-arg value="python" index="1"></constructor-arg> 
		<constructor-arg ref="author" index="3"></constructor-arg>
	</bean>
</beans>

java spring入门示例 java的spring_apache_21


注意:通过使用集合Bean,要引进util

java spring入门示例 java的spring_tomcat_22

5.3、处理特殊字符和空值

处理特殊字符

<property name="name">
	<!-- 使用value子标签处理特殊字符 -->
	<value><![CDATA[1+1<2?]]></value>
</property>

处理空值

<property name="name">
	<!-- 使用null子标签处理空值 -->
	<null/>
</property>

5.4注入list集合类型,值是对象

//学生所学多门课程
private List<Course> courseList;
<!--注入list集合类型,值是对象-->
<property name="courseList">
	<list>
		<ref bean="course1"></ref>
		<ref bean="course2"></ref>
	</list>
</property>

补充:bean的类型

java spring入门示例 java的spring_java spring入门示例_23


工厂bean的实例:来源网络视频

spring配置文件中定义的是MyBean

java spring入门示例 java的spring_spring_24


但是实际返回的是coursebean

java spring入门示例 java的spring_java_25


java spring入门示例 java的spring_spring_26

六、Bean的实例化方法的三种方式

在面向对象的程序中,想要使用某个对象,就需要先实例化这个对象。同样,在Spring中,要想使用容器中的Bean,也需要实例化Bean。实例化Bean有三种方式,分别为构造器实例化、静态工厂方式实例化和实例工厂方式实例化(其中最常用的是构造器实例化)

小提示:在前面的例子中都是使用构造器实例化

注;构造器实例化实例化在前面已经介绍

6.1、静态工厂方式实例化

静态工厂是实例化Bean的另一种方式。该方式要求自己创建一个静态工厂的方法来创建Bean的实例。

java spring入门示例 java的spring_apache_27


java spring入门示例 java的spring_spring_28

java spring入门示例 java的spring_tomcat_29

6.2、实例工厂方式实例化

实例工厂是采用直接创建Bean实例的方式,在配置文件中,通过factory-bean属性配置一个实例工厂,然后使用factory-method属性确定使用工厂中的哪个方法。接下来演示实例工厂实例化的使用:

java spring入门示例 java的spring_java spring入门示例_30


java spring入门示例 java的spring_tomcat_31

七、Bean的作用域

java spring入门示例 java的spring_spring_32


注意:在上表7种作用域中,singleton和prototype是最常用的两种作用域。

7.1、singleton作用域

singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean实例。singleton作用域对于无会话状态的Bean(如Dao 组件、Service组件)来说,是最理想的选择。
在Spring配置文件中,可以使用<bean>元素的scope属性,将Bean的作用域定义成singleton。

<bean id="scope" class="com.itheima.scope.Scope" scope="singleton"/>

java spring入门示例 java的spring_apache_33

java spring入门示例 java的spring_apache_34

7.2、prototype作用域

对需要保持会话状态的Bean(如Struts 2的Action类)应该使用prototype作用域。在使用prototype作用域时,Spring容器会为每个对该Bean的请求都创建一个新的实例
在Spring配置文件中,同样使用<bean>元素的scope属性,将Bean的作用域定义成prototype 。
设置 scope 值是 prototype时候,不是在加载 spring配置文件时候创建对象,在调月getBean方法时候创建多实例对象

<bean id="scope" class="com.itheima.scope.Scope" scope=" prototype "/>

java spring入门示例 java的spring_java spring入门示例_35


java spring入门示例 java的spring_apache_36

八、Bean的生命周期

了解Spring中Bean的生命周期的意义就在于,可以利用Bean在其存活期间的特定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,常会在Bean的初始化销毁执行一些相关操作。

8.1、Spring IOC容器对bean的生命周期进行管理的过程:

① 通过构造器或工厂方法创建bean实例(无参构造)
② 为bean的属性设置值和对其他bean的引用(调用set方法)
③ 调用bean的初始化方法
④ bean可以使用了(对象获取到了)
⑤ 当容器关闭时,调用bean的销毁方法(需要进行配置销毁的方法)

8.2、Bean的生命周期管理

java spring入门示例 java的spring_java spring入门示例_37


java spring入门示例 java的spring_java_38

8.3、singleton作用域

java spring入门示例 java的spring_tomcat_39

java spring入门示例 java的spring_tomcat_40

8.4、prototype作用域

java spring入门示例 java的spring_java spring入门示例_41


java spring入门示例 java的spring_tomcat_42

九、Bean的装配方式(Bean管理)

Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,如
1、手动装配 和 2、自动装配;3、基于XML的装配和4、基于注解(Annotation)的装配

9.1、手动装配

前面的大多数演示都是手动装配,以value或ref的方式(通过set方法或带参构造方式)明确指定属性值都是手动装配

另外还有第三种手动注释方式,

p名称空间注入
使用p名称空间注入,可以简化基于xml配置方式

第一步添加p名称空间在配置文件中,

<beans xmlns="http:// www.springframework. org/ schema/beans"
			 xmlns:xsi="http:// www.w3. org/2001/XMLSchema-instance"
			 xmlns:p="http: // www. springframework. org/schema/p" 
xsi:schemaLocation="http://www. springframework. org/ schema/beans http....
第二步进行属性注入,在bean标签里面进行操作,
set方法注入属性
<bean id="book" class="com.dgut.spring5.Book" p:bnamc="二毛" p:bauthor="无名氏"></bean>

9.2、自动装配

根据指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。

注意:自动装配只能装配引用类型(ref方式)

1、根据类型自动装配:将类型匹配的bean作为属性注入到另一个bean中。

——若IOC容器中有多个与目标bean类型一致的bean,Spring将无法判定哪个bean最合适该属性,所以不能执行自动装配,如下会出错:

java spring入门示例 java的spring_spring_43

2、根据名称自动装配:必须将目标bean的名称和属性名设置的完全相同。

9.2.1、基于XML的自动装配

java spring入门示例 java的spring_spring_44


byType方式

java spring入门示例 java的spring_spring_45


byName方式:bean 的id值和类中的属性名称要一样

java spring入门示例 java的spring_java spring入门示例_46

9.2.2、基于注解(Annotation)的装配

基于XML的装配可能会导致XML配置文件过于臃肿,给后续的维护和升级带来一定的困难。为此,Spring提供了对Annotation(注解)技术的全面支持。

java spring入门示例 java的spring_spring_47


组件命名规则

默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id

使用组件注解的value属性指定bean的id

Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以@Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。

组件被上述注解标识后还需要通过Spring进行扫描才能够侦测到。

包含与排除
<context:exclude-filter>子节点表示要排除在外的目标类
<context:include-filter>子节点表示要包含的目标类
需要与use-default-filters属性配合使用才能够达到效果

=使用注解创建对象=

步骤:
1、引入aop依赖jar包
2、开启组件扫描
3、创建类,并添加注解

java spring入门示例 java的spring_spring_48


java spring入门示例 java的spring_tomcat_49

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<!-- 将基包com.dgut.annotation下加了注解的包都扫描进来 use-default-filters="true"表示不使用默认的扫描方式,而使用子节点配置方式 -->
	<context:component-scan base-package="com.dgut.annotation" use-default-filters="true">
		<!-- 子节点表示要排除在外的目标类,这里不扫描dao -->
		<!-- 
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
		-->
		
		<!-- 子节点表示要包含的目标类,这里只扫描dao,需要结合use-default-filters="false"是使用-->
		<!--
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
		-->
	</context:component-scan>

</beans>

java spring入门示例 java的spring_tomcat_50


java spring入门示例 java的spring_java spring入门示例_51


=使用注解自动注入属性=@Autowire工作机制:

首先使用byType的方式自动装配,如果唯一匹配则装配成功;

如果匹配到多个兼容的Bean,再根据byName的方式进行唯一性确定,如果唯一确定则装配成功;

否则装配失败

@Qualifiter可以辅助@Autowire确定需要装配的Bean的id,即根据属性名称注入

@Resource(Java拓展自带)可以根据byType的方式自动装配,也可以根据byName属性名称注入

java spring入门示例 java的spring_apache_52


基于注解方式实现属性注入

(1)@Autowired:根据属性类型进行自动装配

第一步把service和dao对象创建,在service和dao类添加创建对象注解s

第二步在service注入dao对象,在service类添加dao,类型属性,在属性上面使用注解·

java spring入门示例 java的spring_apache_53


可以使用@Resource(name=“userDaoImpl”)代替@Autowired和@Qualifite实现

java spring入门示例 java的spring_java_54


java spring入门示例 java的spring_java_55

附加:
@Value注解可以代替实现set方法进行赋值

class test001{
	@Value (value = "abc") 
	private String name;

	System.out.println("name==",name);
}

9.3、完全注解开发,不用编写xml文件

java spring入门示例 java的spring_apache_56

java spring入门示例 java的spring_tomcat_57