1. Spring
1. 简介
-
spring框架是由于软件开发的复杂性而创建的
-
目的:解决企业应用开发的复杂性
-
功能:使用基本的JavaBean代替EJB
-
Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架
-
理念:使现有的技术更加容易使用
-
SSM:SpringMVC+Spring+Mybatis
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.19</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.19</version> </dependency>
2. 优点
-
Spring是一个免费的框架
-
Spring轻量级的非入侵式的框架
-
控制反转(IOC),面向切面编程(AOP)
-
支出事务的处理,对框架整合的支持
3. 组成
-
Spring AOP
-
Spring ORM
-
SpringWeb
-
Spring DAO
-
Spring Context
-
Spring Web MVC
-
Spring Core
4. 拓展
-
SpringBoot:
-
快速开发的脚手架
-
快速开发单个微服务
-
约定大于配置
-
-
SpringCloud:
-
基于SpringBoot实现
-
弊端:发展太久之后,违背了原来的理念,配置较为繁琐
2. IOC理论推导
-
UserDao接口
-
UserDaoImpl实现类
-
UserService业务接口
-
UserServiceImpl业务实现类
之前业务中,用户需求可能会影响原来的代码,修改源代码在程序代码量非常大的情况下成本代价非常昂贵
使用set接口实现:
private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; }
-
之前,程序创建对象,控制权在程序员手上
-
使用set注入后,被动的接收对象
IOC本质:
-
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式,
-
控制反转是一种设计思想,DI(依赖注入)是实现IOC的一种方法,控制反转后将对象的创建转移给第三方
IOC是SPring框架的核心内容:Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从IOC容器中取出需要的对象
使用多种方式实IOC:
-
可以使用XML配置:Bean的定义信息和实现分离
-
也可以使用注解配置:Bean的定义信息和实现合为一体
-
新版本的Spring也可以零配置实现IOC
3. IOC创建对象的方式
-
使用无参构造创建对象
<bean id="User" class="com.fish.pojo.User"> <property name="name" value="Fish"/> </bean>
-
使用有参构造创建对象
-
通过下标赋值
<bean id="User" class="com.fish.pojo.User"> <constructor-arg index="0" value="Fish"/> </bean>
-
通过类型赋值
<bean id="User" class="com.fish.pojo.User"> <constructor-arg type="java.lang.String" value="fish"/> </bean>
-
通过参数名赋值
<bean id="User" class="com.fish.pojo.User"> <constructor-arg name="name" value="fish"/> </bean>
-
4. Spring配置
1. bean的配置
-
id:bean的唯一标识符,相当于对象名
-
class:bean对象所对应的全限定名,包名+类名
-
name:别名,可以起多个别名
2. import
一般用于团队开发,可将多个配置文件导入合并一个
5. 依赖注入
1. 构造器注入
-
无参构造
-
有参构造
2. set注入
-
依赖:bean对象的创建依赖于容器
-
注入:bean对象的所有属性由容器来注入
-
普通值注入(value)
<bean id="student" class="com.fish.pojo.Student"> <property name="name" value="fish"/> </bean>
-
引用注入(ref)
<bean id="address" class="com.fish.pojo.Address"/> <bean id="student" class="com.fish.pojo.Student"> <property name="address" ref="address"/> </bean>
-
数组注入(value)
<bean id="student" class="com.fish.pojo.Student"> <property name="books"> <array> <value>局外人</value> <value>春秋</value> <value>人类简史</value> </array> </property> </bean>
-
集合注入(list)
<bean id="student" class="com.fish.pojo.Student"> <property name="hobbies"> <list> <value>唱歌</value> <value>跳舞</value> <value>rap</value> </list> </property> </bean>
-
Map注入
<bean id="student" class="com.fish.pojo.Student"> <property name="card"> <map> <entry key="身份证" value="610629199704031930"/> <entry key="学生证" value="201796084082"/> </map> </property> </bean>
-
set注入
<bean id="student" class="com.fish.pojo.Student"> <property name="games"> <set> <value>LOL</value> <value>PUBG</value> <value>永劫无间</value> </set> </property> </bean>
-
null注入
<bean id="student" class="com.fish.pojo.Student"> <property name="wife"> <null/> </property> </bean>
-
property注入
<bean id="student" class="com.fish.pojo.Student"> <property name="info"> <props> <prop key="姓名">Fish</prop> <prop key="性别">男</prop> <prop key="年龄">24</prop> </props> </property> </bean>
-
p命名空间注入(property直接注入)
<bean id="user" class="com.fish.pojo.User" p:name="咸鱼" p:age="24"/>
-
c命名空间注入(construct-args构造器注入)
<bean id="user2" class="com.fish.pojo.User" c:age="18" c:name="风尘"/>
6. Bean的作用域
-
singleton------单例模式 :只能从容器中get同一个对象
-
prototype------原型模式:每次从容器中get对象的时候,都会产生一个新对象
-
request------在一次请求中有效
-
session------在一个session中有效
-
application------全局有效
-
websocket
7. Bean的自动装配
-
自动装配是spring满足bean依赖的一种方式
-
spring会在上下文中自动寻找,并给bean装配属性
spring中三种装配的方式:
-
xml中的配置
-
Java中的配置
-
隐式的自动装配
1. ByName自动装配:
<bean id="cat" class="com.fish.pojo.Cat"/> <bean id="dog" class="com.fish.pojo.Dog"/> <bean id="people" class="com.fish.pojo.People" autowire="byName"> <property name="name" value="Fish"/> </bean>
2. ByType自动装配:
<bean id="cat" class="com.fish.pojo.Cat"/> <bean id="dog" class="com.fish.pojo.Dog"/> <bean id="people" class="com.fish.pojo.People" autowire="byType"> <property name="name" value="Fish"/> </bean>
小结:
-
byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致
-
bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
3. 注解实现自动装配:
-
导入约束
-
配置注解的支持
<?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"> <context:annotation-config/> </beans>
Autowired:可在属性上使用,也可在set方式上使用,如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解@Autowired完成时,我们可以通过@Qualifier按值查找
小结:@Resource和@Autowired的区别
Autowired通过byType的方式实现,如果属性class有多个相同,可以通过@Qualifier实现
-
@Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现
8. 使用注解开发
-
bean
-
属性如何注入
@Component public class User { public String name; @Value("Fish2") public void setName(String name) { this.name = name; } }
-
衍生的注解
@Component:组件,放在类上说明这个类被spring管理了
@component的衍生注解,在web开发中,会按照mvc三层架构分层
-
dao------@Repository
-
service------@Service
-
controller------@Controller
以上四个注解都是将类注册到spring中,装配bean
-
自动装配
-
作用域
-
小结:xml与注解
-
xml :适用于任何场合,维护简单方便
-
注解:不是自己的类则不能使用,维护比较复杂
9. 使用Java的方式配置spring
JavaConfig是Spring的一个子项目,在Spring4之后,成为了一个核心
10. 代理模式
代理模式的分类:
-
静态代理
-
动态代理
1. 静态代理
-
抽象角色
-
真实角色
-
’代理角色
-
客户
2. 动态代理
-
动态代理的代理类是动态生成的,而静态代理是直接写好的
-
动态代理分为两大类:
-
基于接口的动态代理:JDK动态代理
-
基于类的动态代理:cglib
-
java 字节码实现:javassist
-
Proxy:代理
InvocationHandler:调用处理程序
public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口 private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //生成得到代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this); } //处理代理实例,并返回结果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(rent, args); return result; } }
11. AOP
1. 什么是AOP
AOP:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,利用AOP可以对业务逻辑的各个部分进行隔离,使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,提高程序的开发效率
2. AOP在spring中的作用
提供声明式事务;允许用户自定义切面
-
横切关注点:跨越应用程序多个模块的方法或功能,如日志,安全,缓存,事务等
-
切面(aspect):横切关注点被模块化的特殊对象,是一个类
-
通知(advice):切面必须要完成的工作,是类中的一个方法
-
目标(target):被通知的对象
-
代理(proxy):向目标对象应用通知之后创建的对象
-
切入点(PointCut):切面通知执行的“地点”的定义
-
连接点(JointPoint):与切入点 匹配的执行点
3. 使用Spring实现AOP
通知的五种类型:
-
前置通知
-
后置通知
-
环绕通知
-
异常抛出通知
-
引介通知
使用AOP织入,需要导入一个依赖包!
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.3.19</version> </dependency>
AOP实现方式一:使用原生Spring API接口
<aop:config> <aop:pointcut id="pointCut" expression="execution(* com.fish.service.UserServiceImpl.*(..))"/> <aop:advisor advice-ref="log" pointcut-ref="pointCut"/> <aop:advisor advice-ref="afterLog" pointcut-ref="pointCut"/> </aop:config>
AOP实现方式二:自定义类
<aop:config> <aop:aspect ref="diy"> <aop:pointcut id="point" expression="execution(* com.fish.service.UserServiceImpl.*(..))"/> <aop:before method="before" pointcut-ref="point"/> <aop:after method="after" pointcut-ref="point"/> </aop:aspect> </aop:config>
12. 整合Mybatis
步骤:
-
导入相关Jar包
-
编写配置文件
mybatis-spring:
-
编写数据源配置(dataSource)
-
sqlSessionFactory
-
sqlSessionTemplate
-
需要给接口加是实现类
13. 声明式事务
1.事务(ACID)
-
原子性
-
隔离性
-
一致性
-
持久性