Java 设计模式之桥接模式

桥接(Bridge)是用于把抽象化与实现化解耦,使得二者可以独立变化。这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。

简单来说,可以通过桥接模式实现使用相同的抽象方法、不同的桥接实现类获得不同的结果。

阅读更多

Spring Cloud配置SSH连接统一配置中心

当时在配置ssh连接的时候不知不觉就掉坑里去了,对一些知识点没完全理解;

先说说的掉坑,复制id_rsa文件内的文本出来,放进bootstrap.ymlprivateKey中,如下图

启动报错

1
2
Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'spring.cloud.config.server.git' to org.springframework.cloud.config.server.environment.MultipleJGitEnvironmentProperties failed:
Reason: Property 'spring.cloud.config.server.git.privateKey' is not a valid private key

我们看看官网怎么配spring.cloud.config.server.git

bootstrap.yml

有没有发现不一样,没错,官网配置的privateKey里少了前3行属性
为什么???
因为官网的秘钥在生成时是没有设置秘钥密码的,而我们的秘钥是有密码的,它没办法解密秘钥;
解决办法两种:

  1. ==我们在生成秘钥时也不设置秘钥密码==
  2. ==在yml中配置的git属性添加passphrase==

下面是全配置过程,主要分3步

生成公钥与私钥

打开Git Bash/Terminal,输入ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

引号里面替换成你的邮箱地址或标志自己身份的信息

提示保存秘钥的文件位置,直接回车保持默认位置

设置秘钥密码(直接回车则不设置秘钥密码),生成公钥、秘钥

完成之后可以在/root/.ssh/目录下找到公钥(id_rsa.pub)秘钥(id_rsa)

将公钥添加到git上

复制id_rsa.pub的内容出来

打开github,进入需要拉取文件的仓库,进入设置标签页

点击Add Deploy key

输入GitHub密码确认

刚添加的公钥是灰色的,还没有被使用

在bootstrap.yml中配置

把id_rsa的全部内容复制出来,放到private-key属性

注意:

  1. uri要用ssh形式的地址
  2. ignore-local-ssh-settings设置为true,忽略本地的ssh配置
  3. passphrase内要配置上面设置的秘钥密码

启动项目后,可以在Github的仓库设置中看到公钥已经被使用,变成了绿色。

至此spring-cloud-config使用ssh连接git就配置完成。


修改秘钥密码

打开Git Bash/Terminal,输入 ls-al ~/.ssh 检查之前是否已经生成了SSH key

如果是这样的那就说明已经生成过秘钥,可以选择修改修改私钥密码(passphrase)
输入 ssh-keygen -p

直接回车继续,输入旧密码,然后输入两次新密码

Java 设计模式之适配器模式

适配器模式(Adapter Pattern)是不兼容接口之间的桥梁,可以使一个类加入独立的或不兼容的接口功能。比如计算机通过适配器读取之前无法读取的TF卡;下面用Java模拟这一过程的实现;

阅读更多

Java 中使用Lambda表达式

Lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。使用Lambda表达式的重点是延迟执行deferred execution)。

语法

1
2
3
(Type param1,Type param2,Type param3) -> {
//TODO
}
  1. 参数类型可以省略,编译器可以根据上下文推导;但并不是所有类型都能推导出来,有时需要声明参数类型;
  2. 当参数只有一个时,小/圆括号可以省略;
  3. 当主体只有一条语句时,大括号可以省略;
  4. 当主体只有一条语句时,return可以省略;

实例

参考自runoob.com

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
33
34
35
36
37
38
39
40
41
42
43
44
45
public class Java8Test {
public static void main(String[] args) {
Java8Test test = new Java8Test();
//函数式接口实例
//类型声明
MathOperation addition = (int a, int b) -> a + b;
//不用类型声明
MathOperation subtraction = (a, b) -> a - b;
//大括号中有返回语句
MathOperation multiplication = (a, b) -> {
return a * b;
};
//没有大括号及返回语句
MathOperation division = (int a, int b) -> a / b;

//函数式编程,将函数作为参数传入一个方法
System.out.println("10+5=" + test.operate(10, 5, addition));
System.out.println("10-5=" + test.operate(10, 5, subtraction));
System.out.println("10*b=" + test.operate(10, 5, multiplication));
System.out.println("10/5=" + test.operate(10, 5, division));

//单个参数可以省略括号
GreetingService greetingService1 = message -> System.out.println("Hello" + message);
//不省略括号
GreetingService greetingService2 = (message) -> System.out.println("Hello" + message);
greetingService1.sayMessage("World");
greetingService2.sayMessage("Lambda");
}

interface MathOperation {
int operation(int a, int b);
}

@FunctionalInterface
interface GreetingService {
void sayMessage(String message);
//void sayMessage(String name,String message);
@Override
String toString();
}

private int operate(int a, int b, MathOperation mathOperation) {
return mathOperation.operation(a, b);
}
}

​ 上面的实例中,将MathOperation接口(函数)做为参数传递给operate方法,返回的也是一个方法(函数),这在java 8 之前是无法做到的。这也是java 8的另一新特性,函数式编程;支持函数式编程的语言有很多,如Python、JavaScript等。

在java中Lambda表达式是对象,它必须依附于一类特别的对象类型——函数式接口(Functional Interface)

​ 函数式接口的定义:如果一个接口中,有且只有一个抽象的方法(Object类中的方法不包括在内),那这个接口就可以被看做是函数式接口。

​ 回到上面的实例中,MathOperation接口与GreetingService接口都是函数式接口,其中GreetingService内重写了Object类的toString方法,注解@FunctionalInterface用于声明该接口为函数式接口,如果某个接口(如MathOperation)满足函数式接口定义,编译器也会认为这是一个函数式接口;函数式接口内的方法不可以重载;

变量作用域

  1. Lambda 表达式只能引用声明为final的外层局部变量。
  2. Lambda 表达式中使用局部变量时,该局部变量可以不用声明为final,但是必须不可被后面的代码修改(即隐性的具有final的语义)。
  3. 在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
  4. 在 Lambda 表达式中使用this关键字时,是指创建这个Lambda表达式的方法的this参数。

java中Map、Collection接口常用实现类源码浅析

在Java中集合是常用的数据结构,而MapCollection的实现类有很多,我们常见的有HashMapHashTableTreeMapLinkedHashMapArrayListLinkedlistVectorHashSetTreeSetLinkedHashSet

下面从源码的层面简析这些实现类的特性;

阅读更多