Spring笔记
1.Spring
1.1简介
下载地址:repo.spring.io 不要管怎么来的,下载最新的就是了,Spring反正是向下兼容的
官方说明文档:Core Technologies (spring.io)
关于导包:spring-webmvc(这是最庞大的那个包)/spring-jdbc
- SSH: Struct2+Spring+Hibernate
- SSM: SpringMvc+Spring+Mybatis
1.2优点
- Spring是一个开源的免费框架(容器)
- Spring是一个轻量级的/非侵入式的框架
- 控制反转(IOC),面向切面编程(AOP)
- 支持事物的处理,对框架整合的支持
总结一句话,Spring就是一个轻量级的控制反转(IOC)和面向切面编程的框架
(控制反转:本来是我控制你,现在变成你控制我,主要是在new对象和set对象那一块,作用是用来解耦合,应该是这个意思)
1.3它的组成
主要由七大模块组成
1.4扩展
在Spring官网有这么个介绍,现在的java开发,说白了就是基于spring的开发
-
Spring Boot
- 一个快速开发的脚手架
- 基于SpringBoot可以快速的开发单个的微服务
- 约定大于配置
-
Spring Cloud
- 它是基于Spring Boot实现的
学SpringBoot需要掌握Spring和SpringMVC,如果你前面不了解,那么你听后面整个都是蒙的,没有啥效果,这我是深有体会.Spring非常重要
2.Spring-IOC
2.1理论推导
就是说在以前,我们需要有dao+dao层的Mapper+service+service的impl,当有新的需求增加的时候,就要去修改原码,并且原码改的是new xxximpl();目的是为了拿到这个实现类的对象,此时是程序控制对象;当我们用setxxx方法的时候,就是对象控制程序,因为参数传的就是对象,很灵活,我们只需改变参数就可以了;总结:以前是程序主动创建对象,现在是根据用户传进来的参数是谁,我们再决定为谁创建对象,被动的接收对象,这就是控制反转,主动权由程序变到用户手上
在java中,传参比直接强改代码要好
3.HelloSpring
spring也依赖于配置,简称"配置地狱";xml文件模板在核心技术 (spring.io)
里面的配置元数据那一块,就是用配置文件来创建对象,想初始化也可以初始化
spring默认调用的是无参的构造器,它里面的标签是
总结:基本数据类型用value,自己的对象什么的用ref
若想用有参构造器,在说明文档的Dependencies->dependency Injection->constructor-baseed DI,提供了模板
<!-- 调用无参构造器,id可以说是这个bean标签的唯一标识符,也可以说是这个对象的名字,class就是全限定名-->
<bean id="user" class="com.kuang.pojo.User">
<property name="name" value="tom"></property>
<property name="pwd" value="123"></property>
</bean>
<!-- 有参-->
<bean id="user2" class="com.kuang.pojo.User">
<constructor-arg index="0" value="jack"/>
<constructor-arg index="1" value="42"/>
</bean>
<!-- 有参-->
<bean id="user3" class="com.kuang.pojo.User">
<constructor-arg name="name" value="jack"/>
<constructor-arg name="pwd" value="42"/>
</bean>
必要代码:
ApplicationContext context = new ClassPathXmlApplicationContext("user.xml");//实例化Spring的容器,也可以说获取spring的上下文对象
User user =(User) context.getBean("user");//从容器中拿对象
那么这里怎么就体现了控制反转(Incersion of Control,缩写为IOC)了呢?
对象不由程序创建,由spring创建;程序变成被动的接收对象
依赖注入(Dependency Injection,简称DI):就是利用set方法来进行注入
现在我们就不用去创建对象了,就在xml文件中配置,交给spring打理
对象的创建出现在创建spring容器的时候,就是读取xml文件的时候,也就是获得spring上下文的那个方法
spring容器中的对象只有一份,当你getBean的时候,只要里面的参数相同,那就是同一个对象
4.Spring配置
4.1别名
<alias name="user2" alias="asd"></alias>//就是将你的对象名称换个名字,不过一般不这样取别名,如下,可以取多个别名
<bean id="user2" class="com.kuang.pojo.User" name="u3,u4"></bean>
4.2import
一般用于团队开发,将多个配置文件导入,相当于导包;比如在一个总配置文件中导入这些个包之后,只需要读这个总配置文件就可以使用这三个了
<import resource="admin.xml"></import>
<import resource="user.xml"></import>
<import resource="beans.xml"></import>
5.依赖注入
- 分为构造器注入/Set方式注入/扩展方式注入(c/p)
- 依赖: bean对象的创建依赖于容器
- 注入: bean对象中的所有属性,有容器来注入
5.1普通注入:
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- services -->
<bean id="address" class="com.kuang.pojo.Address">
<property name="street" value="解放西"></property>
</bean>
<bean id="student" class="com.kuang.pojo.Student">
<property name="name" value="tom"></property>
<property name="address" ref="address"></property>
<!-- 数组-->
<property name="books">
<array>
<value>红楼梦</value>
<value>水浒传</value>
<value>西游记</value>
<value>三国演义</value>
</array>
</property>
<!-- map集合-->
<property name="card">
<map>
<entry key="身份证" value="123"></entry>
<entry key="银行卡" value="123456"></entry>
</map>
</property>
<!-- list集合-->
<property name="hobby">
<list>
<value>打篮球</value>
<value>吃饭</value>
<value>看电影</value>
<value>约会</value>
</list>
</property>
<!-- 不设置值得时候-->
<property name="girlfriend">
<null></null>
</property>
<!-- Set集合-->
<property name="games">
<set>
<value>cs'go</value>
<value>cf</value>
</set>
</property>
<!-- Properties类型,就那个配置文件类型-->
<property name="info">
<props>
<prop key="学号">1900130305</prop>
<prop key="姓名">大龙</prop>
</props>
</property>
</bean>
<!-- more bean definitions for services go here -->
</beans>
5.2c命名和p命名空间注入
这需要导入一些约束
p注入就是加了这样一行,p就是property的意思
xmlns:p="http://www.springframework.org/schema/p"
<bean id="product" class="com.kuang.pojo.Product" p:num="12" p:price="10.0"></bean>//可以直接注入属性的值
c注入也是加了这样一行,c就是构造器的意思
xmlns:c="http://www.springframework.org/schema/c"
<bean id="product2" class="com.kuang.pojo.Product" c:_0="123" c:_1="123"></bean>
(在Spring中,创建对象默认调用的是无参构造器,所以必须提供,p标签可以没有有参构造器,c标签必须要有有参构造器)
总结一点:无参和有参都必须提供
6.Bean的作用域(scope属性)
6.1单例模式Singleton(Spring默认机制)
始终只有一个对象
6.2原型模式prototype
就跟传统的一样,每创建一个对象就new一个对象
7.Bean的自动装配
Spring会在上下文中自动寻找,并自动给bean装配属性
传统的:
<!-- 我们的所有装配都在这里显示的定义了-->
<bean id="dog" class="com.kuang.pojo.Dog"></bean>
<bean id="car" class="com.kuang.pojo.Car"></bean>
<bean id="person" class="com.kuang.pojo.Person">
<property name="dog" ref="dog"></property>
<property name="car" ref="car"></property>
</bean>
根据名字自动装配 (根据名字在xml文件中找,但是这个名字的属性的名字,若dog222...就不可以了):
<!-- 自动装配-->
<bean id="dog" class="com.kuang.pojo.Dog"></bean>
<bean id="car" class="com.kuang.pojo.Car"></bean>
<bean id="person" class="com.kuang.pojo.Person" autowire="byName"></bean>
根据类型自动装配: byType,这事就可以随意写名字了,甚至省去id不写也可以,因为是根据类型查找的,但是必须保证这个类型只有一个,不然就不知道找哪个了,
使用注解实现自动装配@Autowired
版本要求:至少jdk1.5,spring2.5
准备条件: 约束和一个标签:
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config/>//这叫注解的支持,有了这个才能使用注解
模板如下:
<?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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<context:annotation-config/>
</beans>
源代码如下,就是说person里面有dog和car对象,你只需要在Person类里面的Dog变量和Car变量上面加@Autowired,注意,这两个都要加,这就实现了自动装配,你就能够拿到这两个对象了
自动装配@Autowired是根据类型匹配的
<bean id="car" class="com.kuang.pojo.Car"></bean>
<bean id="dog" class="com.kuang.pojo.Dog"></bean>
<bean id="person" class="com.kuang.pojo.Person"></bean>
注解是通过反射来实现的,可以不用set方法,也能拿到对象,有时间去深究一下
扩展
@Nullable 这个参数可以为空
public Person(@Nullable String name) {
this.name = name;
}
这是既然是一个注解,那么就可以传参,下面false意味着这个对象可以为空
@Autowired(required = false)
private Car car;
@Qualifier(value = "222")//代表增加一个别名,id取222的时候也可以拿到它,一般在@Autowired环境比较复杂的时候配合使用
此外,使用java自带的注解@Resource也可以自动装配
这个比@Autowired强大,它既可以根据类型匹配,也可以根据名字匹配,默认是名字
8.使用注解开发
9.Spring的AOP
它是oop的延续
特点:
- 能在不修改源代码的情况下,对功能进行增强优化
- 能把相同的功能抽离出来
- 解耦合。不把AOP的代码和其它代码写在一起,专门用一个配置文件来告诉程序,我要在运行时把这个AOP的代码加到某个代码中
AOP的底层实现
它是通过 Spring 提供的动态代理技术去动态的生成代理对象。猫腻就在这里,这个代理对象在调用目标对象方法的同时,加上一些自己的代码,从而实现功能的增强
常用的动态代理技术:
- JDK 代理:基于接口的动态代理技术
- cglib 代理:基于父类的动态代理技术(类似于继承,但底层不是继承实现的)