通过上一篇 IOC & AOP 详解 我们了解了 IOC 和 AOP 这两个思想,下面我们先不去考虑Spring是如何实现这两个思想的,先通过一个银行转账的案例,分析一下该案例在代码层面存在什么问题?分析之后使用我们已有的知识来解决这些问题(痛点)。

其实这个过程就是在一步步分析并手动实现 IOC 和 AOP 。

动态代理的常用实现方式是反射。反射机制是 Java 语言提供的一种基础功能,赋予程序在运行时自省(introspect,官方用语)的能力。通过反射我们可以直接操作类或者对象,比如获取某个对象的类定义,获取类声明的属性和方法,调用方法或者构造对象,甚至可以运行时修改类定义。

动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的,比如用来包装 RPC 调用、面向切面的编程(AOP)。

JDK 自身提供的动态代理,就是主要利用了上面提到的反射机制。但动态代理不止有反射一种实现方式,还有其他的实现方式,比如利用传说中更高性能的字节码操作机制,类似 ASM、cglib(基于 ASM,一个 Java 字节码操作框架)、Javassist 等。简单来说,动态代理是一种行为方式,而反射或 ASM 只是它的一种实现手段而已。

JDK Proxy 和 CGLib 的区别主要体现在以下几个方面:

  • JDK Proxy 是 Java 语言自带的功能,无需通过加载第三方类实现;
  • Java 对 JDK Proxy 提供了稳定的支持,并且会持续的升级和更新 JDK Proxy,例如 Java 8 版本中的 JDK Proxy 性能相比于之前版本提升了很多;
  • JDK Proxy 是通过拦截器加反射的方式实现的;
  • JDK Proxy 只能代理继承接口的类;
  • JDK Proxy 实现和调用起来比较简单;
  • CGLib 是第三方提供的工具,基于 ASM 实现的,性能比较高;
  • CGLib 无需通过接口来实现,它是通过实现子类的方式来完成调用的。

settings.xml 的文件名就可以看出,它是用来设置 maven 参数的配置文件。settings.xml 中包含类似本地仓储位置、修改远程仓储服务器、认证信息等配置。

  • settings.xml 是maven的全局配置文件
  • pom.xml 文件是本地项目配置文件

下面从以下几个问题展开对IOC & AOP的解释

  • 什么是IOC?
  • IOC解决了什么问题?
  • IOC 和 DI 的区别?
  • 什么是AOP?
  • AOP解决了什么问题?
  • AOP为什么叫做切面变成?

首先声明:IOC & AOP不是Spring提出来的,它们在Spring之前其实已经存在了,只不过当时更加偏向于理论。 Spring 在技术层次将这两个思想进行了很好的实现。

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

1
2
3
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

1
2
3
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

1
2
3
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。

请注意,你的答案必须是 子串 的长度,”pwke” 是一个子序列,不是子串。

Given a string, find the length of the longest substring without repeating characters.

Example 1:

1
2
3
Input: "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3.

Example 2:

1
2
3
Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

1
2
3
Input: "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.

Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

MyBatis 是一款优秀的基于 ORM 的半自动轻量级持久层框架。它支持定制化SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的POJO(Plain Old Java Objects,普通老式Java 对象)为数据库的记录。

MyBatis 原本是Apache 的一个开源项目IBatis,2010年6月这个项目由 Apache Software Foundation 迁移到了 Google Code,随后更名为MyBatis

iBatis 一词来源于 “internet” 和 “abatis” 的组合,是一个基于Java的持久层框架。

官网地址

HashMapMap 的一个实现类,它代表的是一种键值对的数据存储形式。

大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序却是不确定的。

HashMap最多只允许一条记录的键为null,允许多条记录的值为null。不保证有序 (比如插入的顺序)、也不保证序不随时间变化。

jdk 8 之前,其内部是由数组 + 链表来实现的,而 jdk 8 对于链表长度超过8的链表将转储为红黑树

HashMap非线程安全,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 CollectionssynchronizedMap方法使HashMap具有线程安全的能力,或者使用ConcurrentHashMap

HashMap数组 + 链表 + 红黑树(JDK1.8 增加了红黑树部分)实现的。JDK 1.8 之所以添加红黑树是因为一旦链表过长,会严重影响 HashMap 的性能,而红黑树具有快速增删改查的特点,这样就可以有效的解决链表过长时操作比较慢的问题。

Java 虽然是面向对象的编程语言,但是依旧保留了一些原始数据类型,同时为了兼容java面向对象的特性,每种原始数据类型,都有对应的包装类型。

原始数据类型:boolean、char、byte、short、int、long、float、double
包装类型:Boolean、Character、Byte、Short、Integer、Long、Float、Double

包装类型是对原始数据类型的一种封装,包含对原始类型数据的存储、基本操作以及两种类型直接的转换。Java5中,引入了自动装箱和自动拆箱功能(boxing/unboxing),Java可以根据上下文,自动进行转换,极大的简化了相关的编程。

Integer就是int对应的包装类,它有一个int类型的字段存储数据,并且提供了基本操作,比如数学运算、类型转换等。

关于Integer的值缓存,是Java5中的一个改进。构造一个Integer对象的正常操作应该是直接使用Integer的构造器,new一个对象出来。但是根据具体实践,大部分的操作都较为集中在有限且较小的数值范围。因此,Java5中新增了静态工厂方法valueOf,在调用它的时候会利用一个缓存机制。缓存的数值范围为[-128, 127]