动力节点—2020最新Spring教程笔记(上)
文章目录
- 1 Spring 概述
- 2 IOC 控制反转
- 2.1 基于XML的DI
- 2.1.1 注入分类
- 2.1.1.1 set注入
- 2.1.1.2 构造注入(了解)
- 2.1.2 自动注入
- 2.2 基于注解的DI
- 3 AOP面向切面编程
- 3.1 AOP术语
- 3.2 AspectJ
- 3.2.1 切入点表达式
- 3.2.2 5种通知类型
根据动力节点2020Spring笔记整理而成,视频地址https://www.bilibili.com/video/BV1nz4y1d7uy/。
1 Spring 概述
Spring 根据代码的功能特点,使用 Ioc 降低业务对象之间耦合度。IoC 使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象了。而是由 Spring容器统一管理,自动“注入”,注入即赋值。 而 AOP 使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中了,而是由 Spring 容器统一完成“织入”。
官网:https://spring.io/
Spring 由 20 多个模块组成,它们可以分为数据访问/集成(Data Access/Integration)、Web、面向切面编程(AOP, Aspects)、提供JVM的代理(Instrumentation)、消息发送(Messaging)、核心容器(Core Container)和测试(Test)。
2 IOC 控制反转
控制反转(IoC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,依赖的管理。
依赖:classA 类中含有 classB 的实例,在 classA 中调用 classB 的方法完成功能,即 classA 对 classB 有依赖。
依赖注入:DI(Dependency Injection),程序代码不做定位查询,这些工作由容器自行完成。
依赖注入 DI 是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
Spring **框架使用依赖注入(**DI)实现IoC。
Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。Spring 容器管理着容器中 Bean 之间的依赖关系,Spring 使用“依赖注入”的方式来管理 Bean 之间的依赖关系。使用 IoC 实现对象之间的解耦和。
具体分为两种,基于 XML 和基于注解的 DI。
2.1 基于XML的DI
2.1.1 注入分类
2.1.1.1 set注入
public class Student{private String name;private int age;private School school;public Student(String name, Integer age, School school) {this.name = name;this.age = age;this.school = school;}public void setName(String name) {this.name = name;}public void setAge(Integer age) {this.age = age;}public void setSchool(School school) {this.school = school;}
}class School{private String name;private String address;public void setAddress(String address) {this.address = address;}public void setName(String schoolName) {this.schoolName = schoolName;}
}
set 注入,相当于调用 set 的方法,使用 <property />
,分为两种,一种是简单类型,即基本类型和String,另一种是引用类型。基本类型和String使用value,引用类型是ref。
<bean id="student" class="com.bjpowernode.ba01.Student" autowire="byName"><property name="name" value="我" /><property name="age" value="20" /><property name="school" ref="school"/>
</bean><bean id="school" class="com.bjpowernode.ba01.School"><property name="name" value="北大" /><property name="address" value="北京" />
</bean>
2.1.1.2 构造注入(了解)
构造注入相当于调用构造器,使用 <constructor-arg />
。
<bean id="student" class="com.bjpowernode.ba01.Student"><constructor-arg name="name" value="我" /><constructor-arg name="age" value="20" /><constructor-arg name="school" ref="school"/>
</bean><bean id="school" class="com.bjpowernode.ba01.School"><property name="name" value="北大" /><property name="address" value="北京" />
</bean>
2.1.2 自动注入
对于某个property是ref类型的,可以自动注入,不用自己写,byName是按照名字注入。在这里指的是Student类的属性school和下面School类的id一样。
<bean id="student" class="com.bjpowernode.ba01.Student" autowire="byName"><property name="name" value="我" /><property name="age" value="20"></property>
<!--自动注入,省略 <property name="school" ref="school"/>-->
</bean><!--id和上面省略的属性名一致-->
<bean id="school" class="com.bjpowernode.ba01.School"><property name="schoolName" value="北大"></property>
</bean>
byType按照类型注入,不要求注入的id和属性名一致。
<bean id="student" class="com.bjpowernode.ba01.Student" autowire="byType"><property name="name" value="我" /><property name="age" value="20"></property>
<!--自动注入,省略 <property name="school" ref="school"/>-->
</bean><!--id和上面的属性名不同-->
<bean id="school1234" class="com.bjpowernode.ba01.School"><property name="schoolName" value="北大"></property>
</bean>
2.2 基于注解的DI
需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。
掌握下面几个注解,@Component,@Repository,@Service,@Controller,@Value,@Autowired,@Qualifier,@Resource。
其中前四个都是定义Bean,@Repository是对DAO实现类使用,@Service对Service实现类使用,@Controller对Controller实现类使用。@Value用于基本类型和String。@Autowired用于自动注入,默认byType,结合@Qualifier实现byName。@Resource默认byName,找不到则byType。
具体如下,第一个例子是byName,School类的对象名称为school1,要求自动注入的名称也是school1.
@Component("school1")
public class School {@Value("北大")private String schoolName;
}@Component("student")
public class Student {@Value("王坤")private String name;@Value("20")private Integer age;@Resource(name="school1") //对应School的名字//@Resource(..)可换成下面两行//@Autowired//@Qualifier("school1")private School school;
}
第二个例子是byType,按照School类去查找,不关心名称。
@Component("school1")
public class School {@Value("北大")private String schoolName;
}@Component("student")
public class Student {@Value("王坤")private String name;@Value("20")private Integer age;@Autowired //或者@Resourceprivate School school;
}
3 AOP面向切面编程
AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程序运行过程。AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB的动态代理。
3.1 AOP术语
(1) 切面(Aspect)
切面泛指交叉业务逻辑。上例中的事务处理、日志处理就可以理解为切面。常用的切面是通知(Advice)。实际就是对主业务逻辑的一种增强。
(2) 连接点(JoinPoint)
连接点指可以被切面织入的具体方法。通常业务接口中的方法均为连接点。
(3) 切入点(Pointcut)
切入点指声明的一个或多个连接点的集合。通过切入点指定一组方法。被标记为 final 的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。
(4) 目标对象(Target)
目 标 对 象 指 将 要 被 增 强 的 对 象 。 即 包 含 主 业 务 逻 辑 的 类 的 对 象 。
(5) 通知(Advice)
通知表示切面的执行时间,Advice 也叫增强。通知定义了增强代码切入到目标代码的时间点,是目标方
法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。
切入点定义切入的位置,通知定义切入的时间。
3.2 AspectJ
3.2.1 切入点表达式
下面为切入点表达式,用中文表述为
execution(访问权限 方法返回值 方法声明(参数) 异常类型)
execution(modifiers-pattern? ret-type-pattern
declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)
举例
execution(public * *(…))
指定切入点为:任意公共方法。
execution(* set*(…))
指定切入点为:任何一个以“set”开始的方法。
execution(* com.xyz.service..(…))
指定切入点为:定义在 service 包里的任意类的任意方法。
execution(* com.xyz.service….(…))
指定切入点为:定义在 service 包或者子包里的任意类的任意方法。“…”出现在类名中时,后
面必须跟“*”,表示包、子包下的所有类。
execution(* …service..*(…))
指定所有包下的 serivce 子包下所有类(接口)中所有方法为切入点
3.2.2 5种通知类型
所有通知方法可以包含一个 JoinPoint 类型参数。该类型的对象本身就是切入点表达式。通过该参数,可获取切入点表达式、方法签名、目标对象等。
AspectJ 中常用的通知有五种类型:
(1)前置通知 @Before
(2)后置通知 @AfterReturing
该注解的 returning 属性就是用于指定接收方法返回值的变量名的,可作为通知的参数
(3)环绕通知 @Around
在目标方法执行之前之后执行。被注解为环绕增强的方法要有返回值,Object 类型。并且方法可以包含一个 ProceedingJoinPoint 类型的参数。接口 ProceedingJoinPoint 其有一个proceed()方法,用于执行目标方法。若目标方法有返回值,则该方法的返回值就是目标方法的返回值。最后,环绕增强方法将其返回值返回。该增强方法实际是拦截了目标方法的执行。
(4)异常通知 @AfterThrowing
该注解的 throwing 属性用于指定所发生的异常类对象,可作为通知的参数
(5)最终通知 @After
无论目标方法是否执行,该通知都会执行。
(6) 定义切入点 @PointCut
可以用一个方法名表示一个切入点表达式,其他通知使用的时候可以用对应的方法取代切入点表达式。
注:在5种通知都有的情况下,如果目标对象的方法本身有异常,执行顺序是Around->Before->方法->Around->After->AfterThrowing,如果没有异常,执行顺序是Around->Before->方法->Around->After->AfterReturing。如果其他的通知出现异常,AfterThrowing同样会执行。特别的,如果 AfterReturing 抛出异常,则5种通知都会执行。
示例如下:
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"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://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:component-scan base-package="com.bjpowernode.service" />--><bean id="someServiceImpl" class="com.bjpowernode.service.SomeServiceImpl"></bean><bean id="myAspect" class="com.bjpowernode.service.MyAspect"/><aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
接口:
package com.bjpowernode.service;public interface SomeService {String doOther(int num);
}
实现类:
package com.bjpowernode.service;public class SomeServiceImpl implements SomeService {@Overridepublic String doOther(int num) {System.out.println("业务方法"+1/num);return String.valueOf(num);}
}
切面类:
package com.bjpowernode.service;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;@Aspect
public class MyAspect {@Before("mypt()")public void myBefore(JoinPoint jp){Signature signature = jp.getSignature();System.out.println("方法定义"+signature);for(Object arg:jp.getArgs()){System.out.println("参数"+arg+","+arg.getClass());}System.out.println("Before");}@AfterReturning(value = "mypt()",returning = "retu")public void myAfterReturning(JoinPoint jp,Object retu){ ;System.out.println("返回的是"+retu);System.out.println("afterReturning");System.out.println(1/0);}@Around(value = "mypt()")public Object myAround(ProceedingJoinPoint pjp) throws Throwable {Object obj = null;System.out.println("Around");System.out.println("环绕通知,通知之前");obj = pjp.proceed();System.out.println("环绕通知,通知之后");return obj;}@AfterThrowing(value = "mypt()",throwing="ex")public void myAfterThrowing(Throwable ex){System.out.println("AfterThrowing:"+ex.getMessage());}@After("mypt()")public void myAfter(){System.out.println("After");
// System.out.println(1/0);}@Pointcut("execution(* com.bjpowernode.service.SomeServiceImpl.do*(..))")private void mypt(){}
}
动力节点—2020最新Spring教程笔记(上)相关推荐
- 动力节点—2020最新MyBatis教程笔记
文章目录 1 介绍 2 快速入门 2.1 操作步骤(P9) 2.1.1 首先创建maven 2.1.2 接着会做一些配置 2.2 在编译的target目录下面缺少xml的解决方式(P11) 2.3 日 ...
- (B站动力节点老杜MySQL教程)MySQL课堂笔记-day01.txt
文章目录 文件来源/资料下载: MySQL课堂笔记-day01.txt 1.sql.DB.DBMS分别是什么,他们之间的关系? 2.什么是表? 3.学习MySQL主要还是学习通用的SQL语句,那么SQ ...
- (B站动力节点老杜MySQL教程)MySQL课堂笔记-day03.txt
文章目录 文件来源/资料下载: MySQL课堂笔记-day03.txt 1.约束 1.1.唯一性约束(unique) 1.2.主键约束 1.3.外键约束 2.存储引擎?(整个内容属于了解内容) 2.1 ...
- (B站动力节点老杜MySQL教程)MySQL课堂笔记-day02.txt
文章目录 文件来源/资料下载: MySQL课堂笔记-day02.txt 1.关于查询结果集的去重? 2.连接查询 2.1.什么是连接查询? 2.2.连接查询的分类? 2.3.在表的连接查询方面有一种现 ...
- Xmind软件 2020最新安装教程讲解
Xmind 2020最新安装教程 1. 首先需要下载Xmind软件(百度网盘链接附上) 2.安装步骤直接就是双击下载好的软件安装即可 3. 安装成功后找到xmind安装目录下的resource目录替换 ...
- Spring动力节点老杜课程学习笔记
没有Spring的时候我们如何进行开发的? 没有Spring为我们服务的,写代码一定是这样的 调用层: public static void main(String[] args) {//创建视图层对 ...
- 动力节点Git安装使用教程,详细到哭
Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理.Git是Linux作者Linus Torvalds为了帮助管理Linux内核开发而开发的一个 ...
- 2020最新Python入门笔记,建议收藏
Python变量和数据类型 数据类型 print语句 注释 Python的注释以 # 开头,后面的文字直到行尾都算注释 # 这一行全部都是注释... print 'hello' # 这也是注释 这里要 ...
- 2020最新Spring框架教程【IDEA版】-Spring框架从入门到精通
第一章:认识Spring spring思维导图 01p/102p Spring认识框架 02p/102p Spring官网浏览以及资源介绍 03p/102p 框架内部模块 第二章 IoC控制反转 04 ...
最新文章
- EqualLogic控制器算法研究一:基本管理
- 迪士尼又出黑科技,可将自然语言脚本转化为VR视频
- [原] 64位win7编译OpenCV SVN版本
- 过滤器解决Struts2重定向漏洞
- MySQL(六)常用语法和数据类型
- java注解管理_JavaSpring【四、Bean管理注解实现】
- python之路_前端基础之Bootstrap 组件
- easyui下拉框option写死_JavaScript_jQuery+easyui中的combobox实现下拉框特效,1.第一种写法:Input框中显示: - phpStudy...
- linux 搭建testlink的问题总结
- opengl顶点数据传送和着色器处理(vao,vbo)
- 问题三十四:怎么用ray tracing画任意长方体(generalized box)
- 【GNN】百度「NLP」面试的一点总结
- c串口一直读到缓存数据_STM32CubeMX之串口不定长数据接收(接收中断+空闲中断)...
- 开发Awesomes系列合集
- 数据分析师面试题目_数据分析师面试的77个常见问题,你准备好了吗?
- 鸿蒙方将腐皮雀跃而有,鸿蒙是谁:生于庄子,火于华为
- CodeForces 379A. New Year Candles
- PAT 7-14 电话聊天狂人
- 你需要理解一下“偏相关系数”及R语言实现
- Java语言 随机点名程序
热门文章
- 汽车基础软件赛道正在经历一轮洗牌
- Java程序设计教程——第三章习题
- ubuntu下安装极品五笔
- linux怎么查看bgp状态,在CentOS中制作BGP路由的教程
- 胖客户端与瘦客户端的区别?
- 天钰FP6378AS5CTR芯片供应,输出电压纹波低,输出电流敢达3A
- FFMPEG视音频编解码学习(一)
- 使用boost库时,无法打开libboost_regex-vc120-mt-1_55.lib
- hsv空间阈值检测matlab,基于HSV色彩空间变换的阴影检测算法——MATLAB实现
- 武汉服务器维修哪里专业报价,入门服务器 武汉IBM X3100报价5500元