Spring入门

JavaSpring入门概述

什么是spring?

Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 **IoC(Inverse Of Control:反转控制) AOP(Aspect Oriented Programming:面向切面编程)**为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。

Spring简介

①Spring是一个开源框架
②Spring为简化企业级开发而生,使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能。同样的功能,在EJB中要通过繁琐的配置和复杂的代码才能够实现,而在Spring中却非常的优雅和简洁。
③Spring是一个IOC(DI)和AOP容器框架。
④Spring的优良特性
[1]非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
[2]依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现。
[3]面向切面编程:Aspect Oriented Programming——AOP
[4]容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
[5]组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
[6]一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。

spring 的体系结构 (如图)

在这里插入图片描述
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。

Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

IOC 与DI的概念和作用

①IOC(Inversion of Control):反转控制。
反转控制资源的获取方式
在应用程序中的组件需要获取资源时(创建自定义类),传统的方式是组件主动的从容器中获取所需要的资源,在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式,增加了学习成本,同时降低了开发效率。
反转控制的思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向——改由容器主动的将资源推送给需要的组件,开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也称为查找的被动形式。控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
简单点来说就是之前你需要用到某个对象的时候你会使用new关键字来创建一个,这个对象是在new了之后才有的;而使用了spring的ioc控制反转,当你需要用到某个对象的时候可以直接去这个ioc容器中获取这个对象,且这个对象在ioc容器初始化的时候就创建后了,你不用自己去new对象。 Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

②DI(Dependency Injection):依赖注入。
容器知道某个主类运行的时候要依赖另一个类,然后容器通过反射的方式将容器中准备好的资源类注入其中。
这也是IOC的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器的资源注入。相对于IOC而言,这种表述更直接。

入门案例

体会ioc控制反转获取对象跟之前的区别

(一)创建一个maven工程
1. 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
创建完项目后会报红,右键项目打开properties

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后点击完成就i不报红了

(二)导包
1.在pom.xnl文件中加入如下坐标 (可复制也可以自己去maven仓库找)

<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>5.2.0.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.2.0.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>5.2.0.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework/spring-expression -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>5.2.0.RELEASE</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/commons-logging/commons-logging -->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>


(三)写配置
1.在类的根路径src/mian/resource下创建的 一个任意名称的 xml 文件 (我这里叫application.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.xsd">



</beans>
  1. 写一个person类
    在这里插入图片描述
package bean;
public class Person {
    private String name;
    private Integer id;
	public Person(String name, Integer id) {
		super();
		this.name = name;
		this.id = id;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", id=" + id + "]";
	}
	public Person() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}   
}

3. 在刚才建立的application.xml文件中给person对象注册

给application.xml文件加入下面内容(在beans标签内)

<!-- bean 标签:用于配置让 spring 创建对象,并且存入 ioc 容器之中
id 属性:对象的唯一标识。后面用来获取对象的标识
class 属性:指定要创建对象的全限定类名
-->

<bean id="person" class="bean.Person">
 <property name="name" value="小李"></property>
 <property name="id" value="100"></property>
</bean>

4.获取person对象
在这里插入图片描述
写一个测试类测试获取person对象
测试类代码内容:

public static void main(String[] args) {
		// 1.使用 ApplicationContext 接口,就是在获取 spring 容器
		ApplicationContext ac = new 
				//标识该配置文件在类的根目录下
				ClassPathXmlApplicationContext("application.xml");
		// 2.根据 bean 的 id 获取对象
		Person person = (Person) ac.getBean("person");
		System.out.println(person);
	}

运行结果:
在这里插入图片描述
到这里一个简单的spring入门案例已经完成了

补充点:
②ioc入门细节:
1.组件(对象)的创建是ioc容器完成的
2.Person类对象是在容器对象创建的过程中容器顺便创建的,容器中的组件都创建完后容器对象才创建完成
3.同一个组件(对象(一个bean标签一个组件))在ioc容器中默认是单实例的,容器启动时就已经创建完成
4.容器中没有该组件时去获取该组件就会报NoSuchBeanDefinitionException错误,不获取也报异常
5.ioc容器在创建这个组件对象时,(用property子标签给属性赋值时)会利用setter方法为JavaBean的属性赋值
6.JavaBean的属性名并不是由子标签声明的属性决定的,而是由JavaBean的getter/setter方法后面的字母决定的
7.利用标签为对象赋值时调用的是该标签创建的对象参数对应的类构造器

bean标签作用:
用于配置对象让 spring 来创建的。
默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功。
属性:
id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。
* singleton :默认值,单例的.
* prototype :多例的.
* request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
* session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
* global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么
	globalSession 相当于 session.
	init-method:指定类中的初始化方法名称。
	destroy-method:指定类中销毁方法名称。

bean 的作用范围和生命周期
单例对象:scope="singleton"
一个应用只有一个对象的实例。它的作用范围就是整个引用。
	生命周期:
	对象出生:当应用加载,创建容器时,对象就被创建了。
	对象活着:只要容器在,对象一直活着。
	对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope="prototype"
每次访问对象时,都会重新创建对象实例。
	生命周期:
	对象出生:当使用对象时,创建新的对象实例。
	对象活着:只要对象在使用中,就一直活着。
	对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

JavaBean的自动装配

由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。
采用自动装配将避免这些错误,并且使配置简单化。

  • 自动装配是使用spring满足bean依赖的一种方法
  • spring会在应用上下文中为某个bean寻找其依赖的bean。

Spring中bean的三种装配机制,分别是:
---- 1.在xml中显式配置;
---- 2.在java中显式配置;
---- 3.隐式的bean发现机制和自动装配。

我们要讲的是第三个自动装配

自动装配:(仅限于对自定义类型的属性有效)

autowire="default/no":不自动装配;不自动为car属性赋值

//按照某种规则自动装配
@ autowire="byName":按照名字;
		private Car car;
			1)、以属性名(car)作为id去容器中找到这个组件,给他赋值;如果找不到就装配null;
			car = ioc.getBean("car");
			
@ autowire="byType" (按类型自动装配)**
使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。
如果不唯一,会报不唯一的异常。

		private Car car;
			1)、以属性的类型作为查找依据去容器中找到这个组件;如果容器中有多个这个类型的组件,报错;
			NoUniqueBeanDefinitionException: 
			No qualifying bean of type [com.atguigu.bean.Car] is defined: 
			expected single matching bean but found 2: car01,car02
			
			2)、没找到呢?装配null
			car = ioc.getBean(Car.class);
			
@ autowire="constructor":
	public Person(Car car) 
		按照构造器进行赋值;
		1)、先按照有参构造器参数的类型进行装配(成功就赋值);没有就直接为组件装配null即可。
		2)、如果按照类型找到了多个;继续以参数的名作为id继续匹配;找到就装配;找不到就null;
		3)、不会报错;
		
自动的为属性赋值:	
    -->
    <bean id="person" class="com.atguigu.bean.Person" autowire="byType">
    </bean>


    <!-- List<Book> books;容器可以把容器中的所有book封装list赋值给这个属性 -->
    <bean id="book01" class="com.atguigu.bean.Book">
        <property name="bookName" value="book1"></property>
    </bean>
    <bean id="book02" class="com.atguigu.bean.Book">
        <property name="bookName" value="book2"></property>
    </bean>
    <bean id="book03" class="com.atguigu.bean.Book">
        <property name="bookName" value="book3"></property>
    </bean>

autowire byName小结:

当一个bean节点带有 autowire byName的属性时。
将查找其类中所有的set方法名,例如setPen,获得将set去掉并且首字母小写的字符串,即pen。
去spring容器中寻找是否有此字符串名称id的对象。
如果有,就取出注入;如果没有,就报空指针异常。

使用注解开发

我们一个个地将组件注册进入到容器太麻烦了,我们可以使用注解的方式将组件批量加入容器中
前提是得导入aop包

将组件快速加入容器中的注解有下面四个:(注解实现要在xml配置扫描包注解)
@Component: 创建对象,加入ioc容器。举例:工具类
@Controller: 同@Component 一般用于表现层的注解。
@Service: 同@Component 一般用于业务层的注解。
@Repository: 同@Component 一般用于持久层的注解。

实现组件自动装配的注解

@Autowired注解
	使用@Autowired注解实现根据类型实现自动装配★  [属性的自动注入]
	   在没有使用@Autowired注解之前,我们要获得一个对象必须得采用new的方式去创建对象,要不然就会出现空指针异常。
	   现在在要创建的对象的引用声明处上加上一个@Autowired注解后,可以不用自己手动new一个对象,@Autowired注解会自动去容器中找到相应的属性的组件,帮我们将要用到的属性注入到相应的位置,不会出现空指针异常
	@Autowired注解原理:
	   @  先按照类型去容器中找到相应的组件
	      #找到一个:找到就直接赋值
	      #找不到: 报错抛异常
	      #找到多个:
	          *如果资源类型的bean不止一个, 会默认根据@Autowired注解标记的成员变量名作为id查找             bean,进行装配★
	                  *若是以变量名作为id没有匹配上的话,就会报错
	                  
@Qualifier注解
		@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
		@Qualifier不能单独使用。
		
@Resource注解
		@Resource如有指定的name属性,先按该属性进行byName方式查找装配;
		其次再进行默认的byName方式进行装配;
		如果以上都不成功,则按byType的方式自动装配。
		都不成功,则报异常。
		
Autowired与@Resource异同:
1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。

XML与注解比较

XML可以适用任何场景 ,结构清晰,维护方便
注解的话不是自己定义的类使用不了,开发简单方便

xml与注解整合开发 :推荐最佳实践
	xml管理Bean
	注解完成属性注入
使用过程中, 可以不用扫描,扫描是为了类上的注解

<context:annotation-config/>  作用:
进行注解驱动注册,从而使注解生效
用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
如果不扫描包,就需要手动配置bean
如果不加注解驱动,则注入的值为null!

案例

1.在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"
      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.xsd">
       
<!--指定注解扫描包 默认扫描spring.bean与spring.service包下的所有类,并将他们都加入到容器中-->
	<context:component-scan
		base-package="spring.bean" />
		 <context:component-scan
		base-package="spring.service" />
		</beans>

2.在bean、service包中创建类

创建好类之后要再类上加上Component等四个注解中的一个即可

bean:

import org.springframework.stereotype.Component;
@Component
public class Person {
	private String name = "利维";
	private Integer id;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public Person(String name, Integer id) {
		super();
		this.name = name;
		this.id = id;
	}
	public Person() {
		super();
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", id=" + id + "]";
	}



Pet.java
import org.springframework.stereotype.Component;
@Component
public class Pet {
	
	private String owner;
	private String name;
	public String getOwner() {
		return owner;
	}
	public void setOwner(String owner) {
		this.owner = owner;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Pet(String owner, String name) {
		super();
		this.owner = owner;
		this.name = name;
	}
	public Pet() {
		super();
	}
	@Override
	public String toString() {
		return "Pet [owner=" + owner + ", name=" + name + "]";
	}

service

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import spring.bean.Person;
@Service
public class PersonService {
	@Autowired
	Person person;
	public void hello() {		
		System.out.println(person);
	}

3.测试类

PersonService personService;
	Pet pet;
	@Test
	public void test() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		PersonService personService = (PersonService) applicationContext.getBean("personService");
		personService.hello();
	}

可以看出我们在配置文件中并没有写bean标签但是同样实现了获取对象的目的
@Autowired注解是实现属性的自动注入

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值