如图3-2所示,微服务启动到配置完成,发生了以下几件事情。
下面介绍两种配置信息的存储方式:
本地仓库是指将所有的配置文件统一写在Config Server工程目录下。config server暴露Http API接口,config client通过调用config server的Http API接口来读取配置文件。
项目结构
pom.xml依赖
org.springframework.boot
spring-boot-starter-parent
org.springframework.cloud
spring-cloud-starter-config
org.springframework.cloud
spring-cloud-config-server
org.springframework.boot
spring-boot-starter-web
该注解使服务成为Spring Cloud Config服务
@EnableConfigServer
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
Spring Config Server的端口号8888,程序名config-server,profiles为native,配置信息存储文件所在的目录为classpath下的config目录。
server:
port: 8888
spring:
application:
name: config-server
profiles:
active: native
cloud:
config:
server:
native:
searchLocations: classpath:config
文件(存储配置信息)路径已经在application.yml中配置了,但是文件名并没有指定,因此URL中要包括文件名。
新建工程config-client,该工程作为Config Client从Config Server读取配置文件
pom.xml依赖
org.springframework.cloud
spring-cloud-starter-config
org.springframework.boot
spring-boot-starter-web
config client向Url地址为http://localhost:8888的Config Server读取配置文件。如果没有读取成功则执行快速失败(fail-fast),读取的是dev文件。配置文件中的变量{spring.application.name}和{spring.profiles.active},两者以 “-” 相连,构成了向Config Server读取的配置文件名,config-client-dev.yml。
spring:
application:
name: config-client
profiles:
active: dev
cloud:
config:
uri: http://localhost:8888
fail-fast: true
在config-client工程写一个API测试接口,读取配置文件的foo变量并返回。
@RefreshScope:由于Spring Boot只会在启动时读取Spring Cloud 中的属性配置,因此Spring Cloud配置服务器中的属性进行更改不会被Spring Boot应用程序自动获取。这个注解就是强制Spring Boot重新读取应用程序配置。
@RefreshScope
@RestController
public class MyController {
@Value("${foo:defaultname}")
String foo;
@RequestMapping("/foo")
public String hi(){
return foo;
}
}
启动工程config-server,再启动config-client,此时控制台会显示config-client向Url地址为http://localhost:8888的Config Server读取了配置文件,程序的启动端口为8888。
server:
port: 8888
spring:
application:
name: config-server-git
cloud:
config:
server:
git:
uri: https://github.com/TLR2019/foo
search-paths: configpassword
username: TLR2019
password: ********
uri为GitHub仓库的地址,search-paths为远程仓库中配置文件所在路径,username和password为GitHub仓库的登录名和密码,如果是私有的仓库登录名和密码是必须的,公开的仓库可以不需要,default-label为仓库的分支,本例是从master读取。
连接的是Mysql数据库
datasource:
druid:
url: jdbc:mysql://localhost:3306/user?characterEncoding=utf-8
username: root
password: ******
driverClassName: com.mysql.jdbc.Driver
initialSize: 5 #初始建立连接数量
minIdle: 5 #最小连接数量
maxActive: 20 #最大连接数量
maxWait: 10000 #获取连接最大等待时间,毫秒
testOnBorrow: true #申请连接时检测连接是否有效
testOnReturn: false #归还连接时检测连接是否有效
timeBetweenEvictionRunsMillis: 60000 #配置间隔检测连接是否有效的时间(单位是毫秒)
minEvictableIdleTimeMillis: 300000 #连接在连接池的最小生存时间(毫秒)
客户端主要是通过读取的数据源往数据库中写入数据
model:lombok的@Data和@ToString注解表示get set方法和tostring方法
@Entity
@Table(name="user")
@Data
@@ToString
public class User {
@Id
private String id;
private String name;
private String password;
}
dao:使用Spring Data Jpa操作数据库
public interface UserRepository extends JpaRepository {
}
service:
@Service
public class UserService {
@Autowired
UserRepository userRepository;
//为了简单,我们就不返回json了
@Transactional
public void save(User user) {
userRepository.save(user);
}
}
controller:
@RefreshScope
@RestController
@RequestMapping("/user/")
public class UserController implements UserControllerApi {
@Autowired
UserService userService;
@RequestMapping("/save")
public String saveUser(User user){
userService.save(user);
return "user";
}
}
为了方便测试,我们使用Swagger。
@Api(value = "修改用户信息", description = "用户信息接口")
public interface UserControllerApi {
@ApiOperation("保存用户信息")
String saveUser(User user);
}
JDK8的版本,首先需要下载Oracle JCE(不限长度的Java加密扩展)来替换默认的,替换java Home路径下的jre\lib\security的文件。
在bootstrap.yml文件中配置密钥。一定要是bootstrap.yml,使用其他名字的配置文件会报错。
encrypt:
key: 1234
启动config Server,启动后可以看到暴露/encrypt和/decrypt接口。
使用postman进行测试,输入http://localhost:8888/encrypt/,选择post提交方式,在body中选择raw格式,并选择test格式,如图。
注意:密文前面要加{cipher}
Spring Cloud知道我们的秘钥,因此可以自动解析。