AOP学习之实现机制

概述

Spring AOP是Spring核心框架的重要组成部分。采用动态代理机制和字节码生成技术实现。

image

实现机制

  • 实现逻辑

    动态代理机制和字节码生成都是在运行期间为目标对象生成一个 代理对象,而将横切逻辑织入到这个代理对象中,系统最终使用的是织入了横切逻辑的代理对象,而不是真正的目标对象。

    Read More

String讲解

API文档描述

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.
You’ll see that every method in the class that appears to modify a String actually creates and returns a brand new String object containing the modification. The original String is left untouched.

“+” 重载

在String中,+被赋予了新的功能。该功能可以实现String字符串的连接。在对String的+操作进行反编译时,可知其内部是如何工作的。

1
2
3
4
5
6
7
8
//源码
public class Concatenation {
public static void main(String[] args) {
String mango = "mango";
String s = "abc" + mango + "def" + 47;
System.out.println(s);
}
}

使用javac Concatenation.java命令获取class文件,然后使用javap -c Concatenation命令得到:

Read More

Interceptor讲解

拦截器接口

1
2
3
4
5
6
7
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;

void postHandle(HttpServletRequest var1, HttpServletResponse var2, Object var3, ModelAndView var4) throws Exception;

void afterCompletion(HttpServletRequest var1, HttpServletResponse var2, Object var3, Exception var4) throws Exception;
}
  • preHandle: 预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器。返回TRUE,继续执行;返回FALSE,中断流程。

  • postHandle: 实现处理器的后处理,但在渲染视图之前。

  • afterCompletion: 整个请求处理完毕回调方法,即在视图渲染完毕时回调

Read More

内部类

结构

1
2
3
4
5
6
7
8
class OutClass {
//属性,方法声明

//内部类
class InnerClass {
//属性,方法声明
}
}

从上可知,内部类的实现很简单,就是将类的定义放在另一个类中,即:place a class definition within another class definition

使用 .this.new

  • .this 使用

    当在内部类中要使用外部类的引用,需要使用.this,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Test {
public void play() {
System.out.println("Test play");
}

//inner class
private class Selector {
public Test getTest() {
//返回一个外部类的引用。也可以:return new Test();
return Test.this;
}
}

public static void main(String[] args) {
Test.Selector selector1 = test.selector();
selector1.getTest().play();
}
}
//output
Test play

Read More

Spring MVC文件下载

文件下载的本质是从服务器读取要下载的文件,把文件转化为流,然后读取流。

文件下载的方式

  • 普遍实现方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 文件下载
* @param response 响应体
* @param file 文件目录
* @return
*/
public static void downLoadFile(HttpServletResponse response, File file) {
if (file == null || !file.exists()) {
return;
}
OutputStream out = null;
try {
//设置response信息头
response.reset();
response.setContentType("application/octet-stream; charset=utf-8");
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
//读取文件流
out = response.getOutputStream();
out.write(FileUtils.readFileToByteArray(file));
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

这种方式比较普通,是在之前的servlet中比较常用,但是在Spring MVC 项目中,还有一种比较优雅的实现方式,详情如下。

  • Spring MVC实现方式
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* 文件下载
* @param fileName 文件名
* @param file 文件目录
* @return
*/
public ResponseEntity<byte[]> download(String fileName, File file) throws IOException {
String dfileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", dfileName);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.CREATED);
}

java接口

接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法。

抽象类与抽象方法

  • 抽象方法

    仅有声明而没有方法体的方法叫抽象方法。

  • 抽象类

    包含抽象方法的类叫做抽象类。

1
为抽象类创建对象是不安全的。即:抽象类不能创建对象。

接口

interface是一个极度抽象的类,interface这个关键字产生一个安全抽象的类,根本没有提供任何具体实现。

注意点
  • 在interface中,所有方法在声明时即使不加public,默认是public
  • interface中可以包含域,这些域隐式的为 static final的。这些域不是接口的一部分,他们的值被存储在该接口的静态存储区域内。
  • 在Java中,不支持多重继承。但是,interface可以支持多重继承。
使用接口的原因
  • 核心原因:为了能够向上转型为多个基类型(策略模式实现的基础)
  • 为了防止客户端程序员创建该类的对象

抽象类与接口的区别

interface是 like a关系,定义该体系的额外功能;抽象类是 is a关系,定义该体系的基本共性内容。

部署GitHub Page

环境
  • git
  • nodejs
  • hexo
配置gitHub
  • 申请github账号,在本地生成ssh秘钥,并配置GitHub
  • 在GitHub上创建一个与GitHub用户名一致的仓库,eg:yourUserName.github.io
  • 将新建的仓库clone到本地目录
安装nodejs
  • nodejs 的安装有多重方式,本例是通过nvm来安装nodejs。首先,安装nvm

  • 配置文件

    • 配置 ~/.bashrc 文件
    • 配置 ~/.bash_profile 文件

~/.bashrc配置

1
2
export NVM_DIR="~/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

~/.bash_profile配置

1
2
3
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
  • 执行sh source ~/.bash_profile

Read More

Fork me on GitHub