lagou 爪哇 1-2 spring 笔记

简介: 任务一 自定义IoC&AOP框架1.1 IoCIoC 全称为 Inversion of Control,翻译为 “控制反转”,它还有一个别名为 DI(Dependency Injection),即依赖注入。1. 谁控制谁 (由 Spring IoC 容器来负责对象的生命周期和对象之间的关系)2. 控制什么 (bean对象创建,属性注入)3. 为何是反转 (依赖的对象由原来的主动获取变成被动接受,所以是反转)4. 哪些方面反转了(所依赖对象的获取被反转了)hibernate中的inverse也是一种IoC

任务一 自定义IoC&AOP框架


1.1 IoC


IoC 全称为 Inversion of Control,翻译为 “控制反转”,它还有一个别名为 DI(Dependency Injection),即依赖注入。


  1. 谁控制谁 (由 Spring IoC 容器来负责对象的生命周期和对象之间的关系)


  1. 控制什么 (bean对象创建,属性注入)



  1. 为何是反转 (依赖的对象由原来的主动获取变成被动接受,所以是反转)


  1. 哪些方面反转了(所依赖对象的获取被反转了)


hibernate中的inverse也是一种IoC


注入形式


  1. 构造器注入


  1. setter注入


  1. 接口注入


1.2 AOP


面向切面


使用场景:事务,日志,调用链追踪,性能分析


1.3 自定义步骤


  1. 统一资源读取


  1. bean对象工厂


  1. bean对象容器


  1. bean属性注入 (循环依赖,三级缓存,创建顺序问题,占位符,二级缓存)


  1. 动态代理实现AOP


jdk动态代理和cglib区别:


  • JDK 动态代理


JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是 InvocationHandler 接口和 Proxy 类。


  • CGLIB 动态代理


如果目标类没有实现接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类。当然,Spring 也支持配置,强制使用 CGLIB 动态代理。


CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final ,那么它是无法使用 CGLIB 做动态代理的。


任务二 Spring IoC高级应用与源码剖析


2.1 BeanFactory和ApplicationContext


ApplicationContext 接口扩展了 BeanFactory 接口,它在 BeanFactory 基础上提供了一些额外的功能。内置如下功能:


  • MessageSource :管理 message ,实现国际化等功能。


  • ApplicationEventPublisher :事件发布。


  • ResourcePatternResolver :多资源加载。


  • EnvironmentCapable :系统 Environment(profile + Properties)相关。


  • Lifecycle :管理生命周期。


  • Closable :关闭,释放资源


  • InitializingBean:自定义初始化。


  • BeanNameAware:设置 beanName 的 Aware 接口。


BeanFactory ApplicationContext
它使用懒加载 它使用即时加载
它使用语法显式提供资源对象 它自己创建和管理资源对象
不支持国际化 支持国际化
不支持基于依赖的注解 支持基于依赖的注解


BeanFactory 也被称为低级容器,而 ApplicationContext 被称为高级容器。


较常见的 ApplicationContext 实现方式:


  1. ClassPathXmlApplicationContext


  1. FileSystemXmlApplicationContext


  1. XmlWebApplicationContext


2.2 BeanPostProcessor

public interface BeanPostProcessor {
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}


可以理解为一个hook,在bean初始化前后完成一些操作,比如rpc框架等在注册bean的前后可以自己完成一些初始化注册等


  1. BeanPostProcessor 的作用域是容器级别的,它只和所在的容器相关 ,当 BeanPostProcessor 完成注册后,它会应用于所有跟它在同一个容器内的 bean 。


  1. BeanFactory 和 ApplicationContext 对 BeanPostProcessor 的处理不同,


  1. ApplicationContext 会自动检测所有实现了 BeanPostProcessor 接口的 bean,并完成注册,但是使用 BeanFactory 容器时则需要手动调用


AbstractBeanFactory#addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法来完成注册


  1. ApplicationContext 的 BeanPostProcessor 支持 Ordered,而 BeanFactory 的


BeanPostProcessor 是不支持的,原因在于ApplicationContext 会对


BeanPostProcessor 进行 Ordered 检测并完成排序,而 BeanFactory 中的


BeanPostProcessor 只跟注册的顺序有关。


2.3 Bean初始化流程


网络异常,图片无法展示
|


流程图


任务三 Spring AOP高级应用与源码剖析


3.1 aopalliance


Spring 对 AOP 联盟接口的变种。


  • Advice


  • Interceptor


  • MethodInterceptor


  • Joinpoint ,连接点接口。每个方法,都对应一个 Joinpoint 对象。


  • Invocation ,调用接口。


  • MethodInvocation ,方法调用接口。


  • ProxyMethodInvocation ,代理方法调用接口。在根目录的包里。


  • ReflectiveMethodInvocation ,反射方法调用实现类。在framework包里。


  • CglibMethodInvocation ,基于 CGLIB 方法调用实现类。在 framework 包里


  • Advice ,定义的横切逻辑。在如下几个时机,可以进行执行:


  • Before :在目标方便调用前执行通知


  • After :在目标方法完成后执行通知。


  • After Returning : 在目标方法执行成功后,调用通知。


  • After Throwing :在目标方法抛出异常后,执行通知。


  • Around :在目标方法调用前后均可执行自定义逻。


3.2 aspectj


对应 org.springframework.aop.aspectj 包。


  • ReflectiveAspectJAdvisorFactory


  • BeanFactoryAspectJAdvisorsBuilder


  • #buildAspectJAdvisors() 方法,构建所有 @Aspect 注解类的增强方法对应的 Advisor 对象。


  • AnnotationAwareAspectJAutoProxyCreator


  • #findCandidateAdvisors() 方法,获得所有增强方法对应的 Advisor 对象。


  • InstantiationModelAwarePointcutAdvisorImpl


  • AbstractAspectJAdvice ,基于 AspectJ ,实现 Advice 接口的 Advice 抽象类。


  • 有如下几个子类:


  • AspectJAroundAdvice


  • AspectJMethodBeforeAdvice


  • AspectJAfterAdvice


  • AspectJAfterReturningAdvice


  • AspectJAfterThrowingAdvice


  • 通过 ReflectiveAspectJAdvisorFactory#getAdvice(...) 方法,构建 AbstractAspectJAdvice 对象。


  • 通过 #invokeAdviceMethodWithGivenArgs(Object[] args) 方法,执行增强 Advice 的方法。【重要


知识点总结


aop 技术


Spring发现涉及到接口那就使用JDK动态代理,如果不涉及接口就使用CGLIB动态代理

从 IOC 容器中获取FactoryBean对象时需要的符号是&

aop 代理对象生成在那一个环节


  • beanpostprocessor


  • postprocessorAfterInitialization


lagou-transfer 基础案例的sql


create database bank;
use bank;
CREATE TABLE `account` (
  `name` varchar(20) NULL,
  `money` int DEFAULT NULL,
  `cardNo` varchar(30) NOT NULL
) ENGINE=InnoDB;
insert into `account` values('韩梅梅', 10000, '6029621011001');
insert into `account` values('李大雷', 5000, '6029621011000');


网络异常,图片无法展示
|


表结构


课堂练习


1)问题⼀:在上述案例实现中,service 层实现类在使⽤ dao 层对象时,直接在

TransferServiceImpl 中通过 AccountDao accountDao = new JdbcAccountDaoImpl() 获得了 dao层对象,然⽽⼀个 new 关键字却将 TransferServiceImpl 和 dao 层具体的⼀个实现类 JdbcAccountDaoImpl 耦合在了⼀起,如果说技术架构发⽣⼀些变动,dao 层的实现要使⽤其它技术,⽐如 Mybatis,思考切换起来的成本?每⼀个 new 的地⽅都需要修改源代码,重新编译,⾯向接⼝开发的意义将⼤打折扣?


2)问题⼆:service 层代码没有竟然还没有进⾏事务控制 ?!如果转账过程中出现异常,将可能导致


数据库数据错乱,后果可能会很严重,尤其在⾦融业务。


参考


https://gitee.com/uza/lagou-java-camp/tree/master/%E7%AC%AC%E4%B8%80%E9%98%B6%E6%AE%B5




目录
相关文章
|
5月前
|
Java Spring
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
【编程笔记】在 Spring 项目中使用 RestTemplate 发送网络请求
120 0
|
20天前
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
20天前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
4月前
|
NoSQL 前端开发 Java
技术笔记:springboot分布式锁组件spring
技术笔记:springboot分布式锁组件spring
43 1
|
4月前
|
Java Linux 程序员
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
技术笔记:Spring生态研习【五】:Springboot中bean的条件注入
|
4月前
|
XML Java 数据安全/隐私保护
技术笔记:Spring中的通知(Advice)和顾问(Advisor)
技术笔记:Spring中的通知(Advice)和顾问(Advisor)
38 0
|
5月前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
96 2
|
5月前
|
Java Spring 容器
【Spring系列笔记】IOC与DI
IoC 和 DI 是面向对象编程中的两个相关概念,它们主要用于解决程序中的依赖管理和解耦问题。 控制反转是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入和依赖查找。
75 2
|
5月前
|
缓存 监控 Java
【Spring系列笔记】AOP
面向切面编程就是面向特定方法编程。通过将横切关注点(cross-cutting concerns)从主要业务逻辑中分离出来,提供一种更好的代码模块化和可维护性。 横切关注点指的是在应用程序中横跨多个模块或层的功能,例如日志记录、事务管理、安全性、缓存、异常处理等。
73 0
|
5月前
|
存储 缓存 Java
【Spring系列笔记】依赖注入,循环依赖以及三级缓存
依赖注入: 是指通过外部配置,将依赖关系注入到对象中。依赖注入有四种主要方式:构造器注入、setter方法注入、接口注入以及注解注入。其中注解注入在开发中最为常见,因为其使用便捷以及可维护性强;构造器注入为官方推荐,可注入不可变对象以及解决循环依赖问题。本文基于依赖注入方式引出循环依赖以及三层缓存的底层原理,以及代码的实现方式。
76 0
下一篇
无影云桌面