文章目录

  • 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教程笔记(上)相关推荐

  1. 动力节点—2020最新MyBatis教程笔记

    文章目录 1 介绍 2 快速入门 2.1 操作步骤(P9) 2.1.1 首先创建maven 2.1.2 接着会做一些配置 2.2 在编译的target目录下面缺少xml的解决方式(P11) 2.3 日 ...

  2. (B站动力节点老杜MySQL教程)MySQL课堂笔记-day01.txt

    文章目录 文件来源/资料下载: MySQL课堂笔记-day01.txt 1.sql.DB.DBMS分别是什么,他们之间的关系? 2.什么是表? 3.学习MySQL主要还是学习通用的SQL语句,那么SQ ...

  3. (B站动力节点老杜MySQL教程)MySQL课堂笔记-day03.txt

    文章目录 文件来源/资料下载: MySQL课堂笔记-day03.txt 1.约束 1.1.唯一性约束(unique) 1.2.主键约束 1.3.外键约束 2.存储引擎?(整个内容属于了解内容) 2.1 ...

  4. (B站动力节点老杜MySQL教程)MySQL课堂笔记-day02.txt

    文章目录 文件来源/资料下载: MySQL课堂笔记-day02.txt 1.关于查询结果集的去重? 2.连接查询 2.1.什么是连接查询? 2.2.连接查询的分类? 2.3.在表的连接查询方面有一种现 ...

  5. Xmind软件 2020最新安装教程讲解

    Xmind 2020最新安装教程 1. 首先需要下载Xmind软件(百度网盘链接附上) 2.安装步骤直接就是双击下载好的软件安装即可 3. 安装成功后找到xmind安装目录下的resource目录替换 ...

  6. Spring动力节点老杜课程学习笔记

    没有Spring的时候我们如何进行开发的? 没有Spring为我们服务的,写代码一定是这样的 调用层: public static void main(String[] args) {//创建视图层对 ...

  7. 动力节点Git安装使用教程,详细到哭

    Git(读音为/gɪt/)是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理.Git是Linux作者Linus Torvalds为了帮助管理Linux内核开发而开发的一个 ...

  8. 2020最新Python入门笔记,建议收藏

    Python变量和数据类型 数据类型 print语句 注释 Python的注释以 # 开头,后面的文字直到行尾都算注释 # 这一行全部都是注释... print 'hello' # 这也是注释 这里要 ...

  9. 2020最新Spring框架教程【IDEA版】-Spring框架从入门到精通

    第一章:认识Spring spring思维导图 01p/102p Spring认识框架 02p/102p Spring官网浏览以及资源介绍 03p/102p 框架内部模块 第二章 IoC控制反转 04 ...

最新文章

  1. EqualLogic控制器算法研究一:基本管理
  2. 迪士尼又出黑科技,可将自然语言脚本转化为VR视频
  3. [原] 64位win7编译OpenCV SVN版本
  4. 过滤器解决Struts2重定向漏洞
  5. MySQL(六)常用语法和数据类型
  6. java注解管理_JavaSpring【四、Bean管理注解实现】
  7. python之路_前端基础之Bootstrap 组件
  8. easyui下拉框option写死_JavaScript_jQuery+easyui中的combobox实现下拉框特效,1.第一种写法:Input框中显示: - phpStudy...
  9. linux 搭建testlink的问题总结
  10. opengl顶点数据传送和着色器处理(vao,vbo)
  11. 问题三十四:怎么用ray tracing画任意长方体(generalized box)
  12. 【GNN】百度「NLP」面试的一点总结
  13. c串口一直读到缓存数据_STM32CubeMX之串口不定长数据接收(接收中断+空闲中断)...
  14. 开发Awesomes系列合集
  15. 数据分析师面试题目_数据分析师面试的77个常见问题,你准备好了吗?
  16. 鸿蒙方将腐皮雀跃而有,鸿蒙是谁:生于庄子,火于华为
  17. CodeForces 379A. New Year Candles
  18. PAT 7-14 电话聊天狂人
  19. 你需要理解一下“偏相关系数”及R语言实现
  20. Java语言 随机点名程序

热门文章

  1. 汽车基础软件赛道正在经历一轮洗牌
  2. Java程序设计教程——第三章习题
  3. ubuntu下安装极品五笔
  4. linux怎么查看bgp状态,在CentOS中制作BGP路由的教程
  5. 胖客户端与瘦客户端的区别?
  6. 天钰FP6378AS5CTR芯片供应,输出电压纹波低,输出电流敢达3A
  7. FFMPEG视音频编解码学习(一)
  8. 使用boost库时,无法打开libboost_regex-vc120-mt-1_55.lib
  9. hsv空间阈值检测matlab,基于HSV色彩空间变换的阴影检测算法——MATLAB实现
  10. 武汉服务器维修哪里专业报价,入门服务器 武汉IBM X3100报价5500元