spring详解(IDEA版)
在这个世界上取得成就的人,都努力去寻找他们想要的机会,如果找不到机会,他们便自己创造机会。你好,我是梦阳辰。期待与你相遇!
文章目录
- 01.spring简介
- 02.IOC理论
- 03.快速入门
- 04.spring的配置
- 05.DI依赖注入
- p/c命名空间注入
- 06.bean的作用域
- 07.Bean的自动装配
- 使用注解实现自动装配
01.spring简介
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大IOC、AOP及Web MVC等功能。Spring可以单独应用于构筑应用程序,也可以和Struts、Webwork、Tapestry等众多Web框架组合使用,并且可以与 Swing等桌面应用程序AP组合。因此, Spring不仅仅能应用于JEE应用程序之中,也可以应用于桌面应用程序以及小应用程序之中。Spring框架主要由七部分组成,分别是 Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring Web和 Spring Web MVC。

Spring框架
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
◆目的:解决企业应用开发的复杂性
◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
◆范围:任何Java应用
Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
Spring的一个最大的目的就是使JAVA EE开发更加容易。同时,Spring之所以与Struts、Hibernate等单层框架不同,是因为Spring致力于提供一个以统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。
Spring的形成,最初来自Rod Jahnson所著的一本很有影响力的书籍《Expert One-on-One J2EE Design and Development》,就是在这本书中第一次出现了Spring的一些核心思想,该书出版于2002年。另外一本书《Expert One-on-One J2EE Development without EJB》,更进一步阐述了在不使用EJB开发JAVA EE企业级应用的一些设计思想和具体的做法。有时间了可以详细的研读一下。
spring官网
https://spring.io/
spring FrameWork的官方文档
https://docs.spring.io/spring-framework/docs/current/reference/html/
spring FrameWork的API文档
https://docs.spring.io/spring-framework/docs/current/javadoc-api/
GitHub地址:
https://github.com/spring-projects/spring-framework
spring理念:使现有的技术更加容易使用,内容很多,整合了现有的技术框架。
SSH:Struct2+Spring+HibernateSSM:SpringMVC+Spring+Mybatis
Features
Core technologies: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP.Testing: mock objects, TestContext framework, Spring MVC Test, WebTestClient.Data Access: transactions, DAO support, JDBC, ORM, Marshalling XML.Spring MVC and Spring WebFlux web frameworks.Integration: remoting, JMS, JCA, JMX, email, tasks, scheduling, cache.Languages: Kotlin, Groovy, dynamic languages.
优点:
Spring是一个开源的免费的框架
Spring是一个轻量级的,非入侵式的框架(不对原来项目产生影响)。
控制反转(IOC)
面向切面编程(AOP)
支持事务的处理,对框架整合的支持。
spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架。
低侵入式设计,代码的污染极低。
独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺。
Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦。
Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。
Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问。
Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部
扩展:

现代化的java开发,就是基于spring的开发。
Spring Boot:一个快速开发的脚手架
基于SpringBoot可以快速的开发单个微服务。
约定大于配置。
Spring Cloud:是基于SpringBoot实现的。
现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要掌握spring及SpringMVC承上启下。
Maven导包:
导入最大的,其他依赖的自动会导入。
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.2</version>
</dependency>
跟mybatis整合
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.2</version>
</dependency>
02.IOC理论
1.UserDao接口
2.UserDaolmpl实现类
3.UserService 业务接口
4.UserServicelmpl 业务实现类

之前实现需求的分析:
程序员主动创建对象,控制权掌握在程序员手里。

使用了set注入后,程序不再具有主动性,而是变成了被动的接收对象。


控制反转loC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现loC的一种方法,也有人认为DI只是loC的另一种说法。没有loC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器,其实现方法是依赖注入(Dependency Iniection,Dl) 。

这种思想,从本质上解决了问题,程序员不需要取管理对象创建了。系统大的耦合性降低,使得可以更加关注于业务上的实现。
这是IOC的原型。
03.快速入门
Hello 对象是谁创建的?hello 对象是由Spring创建的.Hello 对象的属性是怎么设置的?
hello 对象的属性是由Spring容器设置的,这个过程就叫控制反转:
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的.
反转∶程序本身不创建对象,而变成被动的接收对象.依赖注入:就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收.
可以通过newClassPathXmlApplicationContext去浏览一下底层源码.
OK,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的loC,一句话搞定:对象由Spring来创建,管理,装配!
新建pojo类:
public class HelloSpring {private String str;public String getStr() {return str;}public void setStr(String str) {this.str = str;}@Overridepublic String toString() {return "HelloSpring{" +"str='" + str + '\'' +'}';}
}
在resouces下新建beans.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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><!--使用Spring来创建对象,在Spring这些都被称为Beanbean=对象 new HelloSpringid等价于变量名class等价于new的对象property相当于给对象中的属性设置一个值--><bean id="hello" class="com.mengyangchen.pojo.HelloSpring"><property name="str" value="Spring"/></bean></beans>
测试:
public class MyTest {@Testpublic void test(){/*获取Spring的上下文对象*/ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");/*我们的对象交给Spring去管理了,我们要使用,直接去取出来即可*/HelloSpring hello = (HelloSpring)context.getBean("hello");System.out.println(hello.toString());}
}
结果:

默认采用无参构造创建对象。
若要采用有参的构造方法构造对象
1.下标赋值
您可以使用该index属性来明确指定构造函数参数的索引,如以下示例所示:
<bean id="exampleBean" class="examples.ExampleBean"><constructor-arg index="0" value="7500000"/><constructor-arg index="1" value="42"/>
</bean>
2.类型匹配
在上述情况下,如果通过使用type属性显式指定构造函数参数的类型,则容器可以使用简单类型的类型匹配。如下例所示:
如果两个参数都是string:就无法使用。
<bean id="exampleBean" class="examples.ExampleBean"><constructor-arg type="int" value="7500000"/><constructor-arg type="java.lang.String" value="42"/>
</bean>
3.直接通过参数名设置【推荐】
您还可以使用构造函数参数名称来消除歧义,如以下示例所示:
<bean id="exampleBean" class="examples.ExampleBean"><constructor-arg name="years" value="7500000"/><constructor-arg name="ultimateAnswer" value="42"/>
</bean>

对象在你获取前就已经创建了。
在配置文件加载的时候,容器中管理的对象就已经初始化了。

04.spring的配置
别名
<bean id="hello" class="com.mengyangchen.pojo.HelloSpring"><property name="str" value="Spring"/></bean><!--别名--><alias name="hello" alias="hello11"/>

import
一般用户团队开发,它可以将多个配置文件,导入合并为一个,假如现在项目中有多个人开发,这几个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有的beans。xml合并为一个总的。
使用的时候使用总的即可。

内容相同也会合并。
05.DI依赖注入
依赖注入:set注入
依赖:bean对象的创建依赖于容器。
注入:bean对象中的所有属性,由容器来注入。
实体类:
package com.mengyangchen.pojo;import java.util.*;public class Student {private String name;//valueprivate Address address;//refprivate String[] books;private List<String> hobbys;private Map<String,String> card;private Set<String> games;private Properties info;private String wife;public String getName() {return name;}public void setName(String name) {this.name = name;}public Address getAddress() {return address;}public void setAddress(Address address) {this.address = address;}public String[] getBooks() {return books;}public void setBooks(String[] books) {this.books = books;}public List<String> getHobbys() {return hobbys;}public void setHobbys(List<String> hobbys) {this.hobbys = hobbys;}public Map<String, String> getCard() {return card;}public void setCard(Map<String, String> card) {this.card = card;}public Set<String> getGames() {return games;}public void setGames(Set<String> games) {this.games = games;}public Properties getInfo() {return info;}public void setInfo(Properties info) {this.info = info;}public String getWife() {return wife;}public void setWife(String wife) {this.wife = wife;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", address=" + address +", books=" + Arrays.toString(books) +", hobbys=" + hobbys +", card=" + card +", games=" + games +", info=" + info +", wife='" + wife + '\'' +'}';}
}
package com.mengyangchen.pojo;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Address{" +"address='" + address + '\'' +'}';}
}
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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"><!--使用Spring来创建对象,在Spring这些都被称为Beanbean=对象 new HelloSpringid等价于变量名class等价于new的对象property相当于给对象中的属性设置一个值--><bean id="address" class="com.mengyangchen.pojo.Address"><property name="address" value="上海市"/></bean><bean id="student" class="com.mengyangchen.pojo.Student"><!--普通值注入--><property name="name" value="梦阳辰"/><!--bean注入--><property name="address" ref="address"/><!--数组注入--><property name="books"><array><value>平凡的世界</value><value>追着风筝的人</value><value>活着</value></array></property><!--list注入--><property name="hobbys"><list><value>打篮球</value><value>玩游戏</value><value>看电影</value></list></property><!--Map注入--><property name="card"><map><entry key="学号" value="2341234"/><entry key="学院" value="计算机学院"/><entry key="班级" value="A1811"/></map></property><!--set注入--><property name="games"><set><value>英雄联盟</value><value>王者荣耀</value></set></property><!--null注入--><property name="wife"><null/></property><!--Properties注入--><property name="info"><props><prop key="学号">2342424</prop><prop key="姓名">梦阳辰</prop></props></property></bean>
</beans>
测试:
@Testpublic void test(){/*获取Spring的上下文对象*/ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");/*我们的对象交给Spring去管理了,我们要使用,直接去取出来即可*/Student student = (Student) context.getBean("student");System.out.println(student.toString());}
结果:

注入方式:
构造器注入
set方式注入
扩展方式注入。
p/c命名空间注入
具有p-命名空间的XML快捷方式(set注入)
p-namespace允许您使用bean元素的属性(而不是嵌套 元素)来描述协作bean的属性值,或同时使用这两者。
Spring支持带有XML定义的命名空间的可扩展配置格式。beans本章讨论的配置格式在XML Schema文档中定义。但是,p命名空间未在XSD文件中定义,仅存在于Spring的核心中。
<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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean name="classic" class="com.example.ExampleBean"><property name="email" value="someone@somewhere.com"/></bean><bean name="p-namespace" class="com.example.ExampleBean"p:email="someone@somewhere.com"/>
</beans>
具有c-namespace的XML快捷方式(构造器注入)
与具有p-namespace的XML Shortcut相似,在Spring 3.1中引入的c-namespace允许使用内联属性来配置构造函数参数,而不是嵌套constructor-arg元素。
下面的示例使用c:名称空间执行与 基于构造函数的依赖注入相同的操作
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="beanTwo" class="x.y.ThingTwo"/><bean id="beanThree" class="x.y.ThingThree"/><!-- traditional declaration with optional argument names --><bean id="beanOne" class="x.y.ThingOne"><constructor-arg name="thingTwo" ref="beanTwo"/><constructor-arg name="thingThree" ref="beanThree"/><constructor-arg name="email" value="something@somewhere.com"/></bean><!-- c-namespace declaration with argument names --><bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"c:thingThree-ref="beanThree" c:email="something@somewhere.com"/></beans>
例如:
<?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"xmlns:p="http://www.springframework.org/schema/p"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd"><!--p命名空间注入,可以之间注入属性的值--><bean id="user" class="com.mengyangchen.pojo.User" p:name="梦阳辰" p:age="19"/><!--c命名空间注入--><bean id="user2" class="com.mengyangchen.pojo.User" c:age="18" c:name="阳辰"/></beans>
注意点:使用前需要导入xml约束。
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

06.bean的作用域

单例模式(singleton)默认机制
换句话说,当您定义一个bean定义并且其作用域为单例时,Spring IoC容器将为该bean定义所定义的对象创建一个实例。该单个实例存储在此类单例bean的高速缓存中,并且对该命名bean的所有后续请求和引用都返回该高速缓存的对象。下图显示了单例作用域的工作方式

<bean id="accountService" class="com.something.DefaultAccountService"/><!-- the following is equivalent, though redundant (singleton scope is the default) -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>
原型模式(prototype)
每次对特定bean提出请求时,bean部署的非单一原型范围都会导致创建一个新bean实例。也就是说,该Bean被注入到另一个Bean中,或者您可以通过getBean()容器上的方法调用来请求它。通常,应将原型作用域用于所有有状态Bean,将单例作用域用于无状态Bean。

以下示例将bean定义为XML原型:
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
其余的request,session,application,这些只能在web开发中使用到。
07.Bean的自动装配
自动装配是spring满足依赖一种方式!
spring会在上下文中寻找,并自动给bean装配属性。
在spring中有三种装配的方式
1.xml中显示的配置。
2.在java中显示配置。
3.隐式的自动装配**【重要】**。
实体类:
package com.mengyangchen.pojo;public class Cat {public void shout(){System.out.println("miao~~");}
}
package com.mengyangchen.pojo;public class Dog {public void shout(){System.out.println("wang~~");}
}
package com.mengyangchen.pojo;public class People {private Cat cat;private Dog dog;private String name;public Cat getCat() {return cat;}public void setCat(Cat cat) {this.cat = cat;}public Dog getDog() {return dog;}public void setDog(Dog dog) {this.dog = dog;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "People{" +"cat=" + cat +", dog=" + dog +", name='" + name + '\'' +'}';}
}
手动装配:
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="cat" class="com.mengyangchen.pojo.Cat"></bean><bean id="dog" class="com.mengyangchen.pojo.Dog"></bean><bean id="people" class="com.mengyangchen.pojo.People"><property name="name" value="梦阳辰"/><property name="cat" ref="cat"/><property name="dog" ref="dog"/></bean>
</beans>
自动装配:
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="cat" class="com.mengyangchen.pojo.Cat"></bean><bean id="dog" class="com.mengyangchen.pojo.Dog"></bean><!--byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean Id--><!--byType:会自动在容器上下文中查找,和自己对象类型对应的bean Id--><bean id="people" class="com.mengyangchen.pojo.People" autowire="byName"><property name="name" value="梦阳辰"/></bean>
</beans>
小结:byName时,需要保证所有的bean的id唯一,并且这个bean需要和对应那个注入的属性的set方法一致。
使用注解实现自动装配
使用注解须知:
1.导入约束
xmlns:context="http://www.springframework.org/schema/context"
2.配置注解支持
<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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/>beans>
测试:
<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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><bean id="cat" class="com.mengyangchen.pojo.Cat"/><bean id="dog" class="com.mengyangchen.pojo.Dog"/><bean id="people" class="com.mengyangchen.pojo.People"/>beans>
@Autowired在属性上使用即可(也可以放在set方法上;可以不需要set方法)
package com.mengyangchen.pojo;import org.springframework.beans.factory.annotation.Autowired;public class People {@Autowiredprivate Cat cat;@Autowiredprivate Dog dog;private String name;public Cat getCat() {return cat;}public void setCat(Cat cat) {this.cat = cat;}public Dog getDog() {return dog;}public void setDog(Dog dog) {this.dog = dog;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "People{" +"cat=" + cat +", dog=" + dog +", name='" + name + '\'' +'}';}
}
使用Autowired我们可以不用编写set方法,前提是这个自动装配的属性在IOC(spring)容器中存在,且符合名字byName。
@Nullable 字段标记了这个注解,说明这个字段可以为null

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifier(value=“xxx”")去配置@Autowired的使用,指定一个唯一的bean对象注入!
也可以用@resource注解,两者的区别:
两者都是用来自动装配
@Autowired默认通过byName方式实现,而且必须要求这个对象存在。
@Resource默认通过byName的方式实现,否则通过byType。
A man’s best friends are his ten fingers。

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
