javase:oop
mysql:持久化
html+css+js+jquery框架:视图,框架不熟练,css不好;
javaweb:独立开发mvc三层架构的网站了,原始
ssm:框架:简化了我们的开发流程,配置也开始较为复杂;
以上打成war:通过tomcat运行
spring再简化:SpringBoot -打成jar;其中内嵌tomcat;微服务架构
服务越来越多:springcloud 用来管理纷杂的配置
官方:提供一个快速生成的网站,IDE集成了这个网站!
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.4.0
com.mi
helloworld
0.0.1-SNAPSHOT
helloworld
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-maven-plugin
自动配置:
pom.xml
启动器
org.springframework.boot
spring-boot-starter
启动器:说白就是SpringBoot的启动场景
比如spring-boot-web,他就会帮我们自动导入web环境所有的依赖
SpringBoot会将所有的功能场景,变成一个个启动器
我们要使用什么功能,就只需要找到对应的启动器就可以了 starter
主程序
//@SpringBootApplication:标注这个类是一个SpringBoot的应用
@SpringBootApplication
public class Springboot01HelloworldApplication {
public static void main(String[] args) {
//将SpringBoot应用启动
SpringApplication.run(Springboot01HelloworldApplication.class, args);
}
}
注解
@SpringBootConfiguration:SpringBoot的配置
@Configuration:spring配置类
@Component:说明这也是一个Component组件
@EnableAutoConfiguration:自动配置
@AutoConfigurationPackage:自动配置包
@Import({Registrar.class}):导入选择器'包注册'
@Import({AutoConfigurationImportSelector.class}): 自动配置导入选择
//获取所有的配置
List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
获取候选的配置
protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
结论:SpringBoot所有自动配置都是在启动的时候扫描并加载:Spring.factories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有了对应的启动器了,有了启动器,我们自动装配就会生效,然后就配置成功了
springboot在启动的时候,在类路径下/META-INF/spring.factories获取指定的值
关于SpringBoot,谈谈你的理解
全面接管SpringMVC的配置! 实操
# k = v
# 对空格要求十分高
# 普通的key-value
name: xiaomi
# 对象
student:
name: xiaomi
age: 3
# 行内写法
student: {name: xiaomi,age: 3}
# 数组
pets:
- cat
- dog
- pig
pets: [cat,dog,pig]
yaml可以直接给实体类赋值
public class Person {
//Person{name='xiaomi',
// age=18, happy=false,
// birth=Mon Nov 23 00:00:00 CST 2020,
// maps={k1=v1, k2=v2},
// lists=[code, music, girl],
// dog=Dog{name='旺财', age=3}}
private String name;
private Integer age;
private Boolean happy;
private Date birth;
private Map maps;
private List
person:
name: xiaomi${random.uuid}
age: ${random.int}
happy: false
birth: 2020/11/23
maps: {k1: v1,k2: v2}
hello: happy
lists:
- code
- music
- girl
dog:
name: ${person.hello:hello}_旺财
age: 3
server:
port: 8081
spring:
profiles:
active: dev
---
server:
port: 8082
spring:
profiles: dev
---
server:
port: 8083
spring:
profiles: test
jar:webapp!
自动装配
SpringBoot到底帮我们配置了什么,我们能不能进行修改?能修改哪些东西?能不能扩展?
要解决的问题:
总结:
1.在springboot,我们可以使用一下方式处理静态资源
2.优先级:resource>static(默认)>public
结论:只要需要使用thymeleaf,只需要导入对应的依赖就可以了!我们将html放在我们的templates目录下即可!
org.thymeleaf
thymeleaf-spring5
org.thymeleaf.extras
thymeleaf-extras-java8time
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
使用thymeleaf
Title
//如果你想diy一些定制化的功能,只要写这个组件,然后将它交给springboot,springboot就会帮我们自动装配
//全面扩展SpringMVC
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
// public interface ViewResolver 实现了视图解析器接口的类,我们就可以把它看做视图解析器
@Bean
public ViewResolver MyViewResolver(){
return new MyViewResolver();
}
//自定义了一个自己的视图解析器
public static class MyViewResolver implements ViewResolver{
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
}
在springboot中,有非常多的xxxxAutoConfiguration帮助我们进行扩展配置,只要看见了这个东西,我们就要注意了
1.首页配置:
1.注意点,所有页面的静态资源都需要使用thmeleaf来接管;
2.url: @{}
2.页面国际化:
1.我们需要配置i18n文件
2.我们如果需要在项目中进行自动切换,我们需要自定义一个组件LocaleResolver
3.记得将自己写的组件配置到Spring容器 @Bean
4. #{}
1.通过thymeleaf和index.html进行绑定
2.编写LoginController
@Controller
public class LoginController {
@RequestMapping("/user/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
Model model, HttpSession session){
//具体的业务:
if(!StringUtils.isEmpty(username) && "123456".equals(password)){
session.setAttribute("loginUser",username);
return "redirect:/main.html";
} else {
//告诉用户你登录失败了
model.addAttribute("msg","用户名或者密码错误");
return "index";
}
}
}
3.实现中英文界面切换
public class MyLocaleResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
String language = request.getParameter("l");
Locale locale = Locale.getDefault();//如果没有就是用默认
//如果请求的连接携带了地区化的参数
if(!StringUtils.isEmpty(language)){
//zh_CN
String[] split = language.split("_");
//国家,地区
locale = new Locale(split[0], split[1]);
}
return locale;
}
}
JavaConfig里添加bean
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
4.添加登录过滤器
public class LoginHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//登录成功之后,应该有用户的session
Object loginUser = request.getSession().getAttribute("loginUser");
if(loginUser==null){//没有登录
request.setAttribute("msg","没有权限,请先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else {
return true;
}
}
}
编写完过滤器 要记得在JavaConfig类中添加重写方法
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginHandlerInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/css/*","/js/**","/img/**");
}
1.提取公共页面
th:fragment=“sidebar”
th:replace="~{commons/commons::sidebar}
如果要传递参数,可以直接使用()
传参,接收判断即可
th:class="${active=='main.html'?'nav-link active':'nav-link'}"
2.列表循环展示
id
lastName
email
gender
department
birth
操作
[[${emp.getLastName()}]]
1.按钮提交
添加员工
2.跳转到页面
@GetMapping("/emp")
public String toAddpage(Model model){
//查出所有部门的信息
Collection departments = departmentDao.getDepartments();
model.addAttribute("departments",departments);
return "emp/add";
}
3.添加员工成功
html创建一个add.html的添加页面 表格模式
4.返回首页
@PostMapping("/emp")
public String toEmp(Employee employee){
System.out.println("save=>"+employee);
employeeDao.save(employee);//调用底层业务的方法保存员工的信息
//添加的操作 forward
return "redirect:/emps";
}
//去员工的修改页面
@GetMapping("/emp/{id}")
public String toUpdateEmp(@PathVariable("id")Integer id,Model model){
//查出原来的数据
Employee employee = employeeDao.getEmployeeById(id);
model.addAttribute("emp",employee);
//查出所有部门的信息
Collection departments = departmentDao.getDepartments();
model.addAttribute("departments",departments);
return "emp/update";
}
@PostMapping("/updateEmp")
public String updateEmp(Employee employee){
employeeDao.save(employee);
return "redirect:/emps";
}
@GetMapping("/delEmp/{id}")
public String deleteEmp(@PathVariable("id")int id){
employeeDao.delete(id);
return "redirect:/emps";
}
只需要在templates中创建一个error文件夹,把404.html丢进去即可
记得修改路径!去掉static
@RequestMapping("/user/logout")
public String logout(HttpSession session){
session.invalidate();
return "redirect:/index.html";
}
如何快速搭建web应用?
1.有一套自己熟悉的后台模板:工作必要!x-admin
2.前端界面:至少自己能够通过前端框架,组合出来一个网站页面
3.让这个网站能够独立运行!
springboot是什么?
微服务
写出第一个hello world
探究源码~得出自动装配原理
配置 yaml
多文档环境切换
静态资源映射
Thymeleaf th:xxx
springboot如何扩展mvc javaConfig
如何修改springboot的默认配置
CRUD
国际化
拦截器
定制首页,错误页
这次:
结合spring
1、创建项目,勾选jdbc相关配置
org.springframework.boot
spring-boot-starter-jdbc
mysql
mysql-connector-java
runtime
2、用yaml配置jdbc的连接参数
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&charsetEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
3、连接数据库
4、创建controller测试数据
@RestController
public class JDBCController {
@Autowired
JdbcTemplate jdbcTemplate;
//查询数据库的所有信息
//没有实体类,数据库的东西,
@GetMapping("/userlist")
public List
6、配置Druid
1.添加依赖
com.alibaba
druid
1.2.3
2.配置里添加参数
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&charsetEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
#Spring Boot 默认是不注入这些属性值的,需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
#配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
#如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority
#则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
3.创一个config文件夹存放DruidConfig类
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
//后台监控:web.xml,ServletRegistrationBean
//应为SpringBoot内置了servlet容器,所以没有web.xml 替代方法:ServletRegistrationBean
@Bean
public ServletRegistrationBean statViewServlet(){
ServletRegistrationBean bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
//后台需要有人登陆,配置账号密码
HashMap initParameters = new HashMap<>();
//增加配置
initParameters.put("loginUsername","admin");//登陆key 是固定的 loginUsername loginPassword
initParameters.put("loginPassword","123456");
//允许谁可以访问
initParameters.put("allow","");
//禁止谁能访问
//initParameters.put("xiaomi","192.168.11.123");
bean.setInitParameters(initParameters);//设置初始化参数
return bean;
}
//filter
@Bean
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean<>();
bean.setFilter(new WebStatFilter());
//可以过滤哪些请求呢
Map initParameters = new HashMap<>();
initParameters.put("exclusions","*.js,*.css,/druid/*");
bean.setInitParameters(initParameters);
return bean;
}
}
整合包
mybatis-spring-boot-start
1.导入包
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.1
2.配置文件
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 整合mybatis
mybatis.type-aliases-package=com.mi.pojo
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
3.mybatis配置(UserMapper.xml)
4.编写sql
insert into mybatis.user (id, name, pwd) VALUES (#{id},#{name},#{pwd})
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
delete from mybatis.user where id=#{id}
5.编写接口和User类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
@Mapper
@Repository
public interface UserMapper {
List queryUserList();
User queryUserById(int id);
int addUser(User user);
int updateUser(User user);
int deleteUser(int id);
}
6.service层调用dao层
7.controller调用service层
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/queryUserList")
public List queryUserList(){
List userList = userMapper.queryUserList();
for (User user : userList) {
System.out.println(user);
}
return userList;
}
//添加一个用户
@GetMapping("/addUser")
public String addUser(){
userMapper.addUser(new User(10,"小小米","159753"));
return "ok";
}
//修改一个用户
@GetMapping("/updateUser")
public String updateUser(){
userMapper.updateUser(new User(10,"小小米","798765465"));
return "ok";
}
//根据id删除用户
@GetMapping("/deleteUser")
public String deleteUser(){
userMapper.deleteUser(10);
return "ok";
}
}
M:数据和业务
C:交接
V:HTML
学习目标:
前后端分离
Vue+SpringBoot
后端时代:前端使用管理静态页面;html==>后端。模板引擎JSP=>后端是主力
前后端分离时代:
产生的一个问题:
解决方案:
Swagger
官网:https://swagger.io/
在项目使用swagger需要springbox
1.新建一个SpringBoot - web项目
2.导入相关依赖
io.springfox
springfox-swagger2
3.0.0
io.springfox
springfox-swagger-ui
3.0.0
3.0还需要配置
io.springfox
springfox-boot-starter
3.0.0
3.编写一个hello工程
4.配置Swagger==>Config
@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig {
}
5.测试运行:3.0为:http://localhost:8080/swagger-ui/index.html
Docket.select()
//配置了Swagger的Docket的bean实例
//enable是否启动swagger,如果为False则Swagger不能在浏览器访问
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors,配置要扫描接口的方式
//basePackage:指定要扫描的包
//any():扫描全部
//none():不扫描
//.withClassAnnotation():扫描类上的注解
//.withMethodAnnotation():扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.mi.controller"))
//paths()过滤什么路径
/*.paths(PathSelectors.ant("/mi/**"))*/
.build();
}
我只希望我的Swagger在生产环境中使用,在发布的时候不使用?
配置API文档的分组
.groupName("小米")
配置多个分组;多个Docket实例即可
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("A");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("B");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("C");
}
实体类
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("用户名")
public String username;
@ApiModelProperty("密码")
public String password;
}
控制类
GetMapping(value = "/hello")
public String hello(){
return "hello";
}
//只要我们的接口中,返回值存在实体类,他就会被扫描到
@PostMapping(value = "/user")
public User user(){
return new User();
}
@ApiOperation("hello控制类")
@GetMapping(value = "/hello2")
public String hello(@ApiParam("用户名") String username){
return "hello"+username;
}
@ApiOperation("Post测试类")
@PostMapping(value = "/postt")
public User postt(@ApiParam("用户名")User user){
int i=5/0;
return user;
}
总结:
1.我们可以通过Swagger给一些比较难理解的属性或者接口,增加注释信息
2.接口文档实时更新
3.可以在线测试
Swagger是一个优秀的工具,几乎所有大公司都在使用它
【注意点】在正式发布的时候,关闭Swagger!出于安全考虑,而且节省运行的内存;
异步任务~
@Service
public class AsyncService {
//告诉Spring这是一个异步的方法
@Async
public void hello(){
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("数据正在处理。。。");
}
}
定时任务~
@Service
public class ScheduledService {
//在一个特定的时间执行这个方法~ Timer
/*
0 54 11 * * ? 每天10点15分30 执行一次
30 0/5 10,18 * * ? 每天10点和18点,每隔五分钟执行一次
0 15 10 ? * 1-6 每个月的周一到周六 10.15分钟执行一次
*/
//cron 表达式
//秒 分 时 日 月 周几
@Scheduled(cron = "0 54 11 * * ?")
public void hello(){
System.out.println("hello,你被执行了~");
}
}
邮件任务~
@Autowired
JavaMailSenderImpl mailSender;
@Test
void contextLoads() {
//一个简单的邮件
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("美好的事情即将发生");
mailMessage.setText("谢谢你的狂神说java系列课程");
mailMessage.setTo("[email protected]");
mailMessage.setFrom("[email protected]");
mailSender.send(mailMessage);
}
@Test
void contextLoads2() throws MessagingException {
//一个复杂的邮件
MimeMessage mimeMessage = mailSender.createMimeMessage();
//组装
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
helper.setSubject("小米你好呀~plus");
helper.setText("谢谢你的狂神说Java系列课程~
",true);
//附件
helper.addAttachment("1.jpg",new File("C:\\Users\\xiaososa\\Desktop\\1.jpg"));
helper.addAttachment("2.jpg",new File("C:\\Users\\xiaososa\\Desktop\\1.jpg"));
helper.setTo("[email protected]");
helper.setFrom("[email protected]");
mailSender.send(mimeMessage);
}
/**
*
* @param html
* @param subject
* @param text
* @throws MessagingException
*/
public void sendMail(boolean html,String subject,String text) throws MessagingException {
//一个复杂的邮件
MimeMessage mimeMessage = mailSender.createMimeMessage();
//组装
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true);
helper.setSubject(subject);
helper.setText(text,true);
//附件
helper.addAttachment("1.jpg",new File("C:\\Users\\xiaososa\\Desktop\\1.jpg"));
helper.addAttachment("2.jpg",new File("C:\\Users\\xiaososa\\Desktop\\1.jpg"));
helper.setTo("[email protected]");
helper.setFrom("[email protected]");
mailSender.send(mimeMessage);
}
TaskScheduler 任务调度者
TaskExecutor 任务执行者
@EnableScheduling//开启定时功能的注解
@Scheduled//什么时候执行~
Cron表达式
SpringBoot操作数据:spring-data jpa jdbc mongodb redis!
SpringData也是和SpringBoot齐名的项目
说明:在SpringBoot2.x之后,原来使用的jedis被替换为lettuce?
jedis:采用的直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用jedis pool连接池,更像BIO模式
lettuce:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据了,更像NIO模式
源码分析:
@Bean
@ConditionalOnMissingBean(
name = {"redisTemplate"}
)//我们可以自己定义一个RedisTemplate来替换这个默认的
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate
1、导入依赖
org.springframework.boot
spring-boot-starter-data-redis
2、配置连接
# 配置redis
spring.redis.host=127.0.0.1
spring.redis.port=6379
3、测试
@SpringBootTest
class Redis02SpringbootApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
//redisTemplate 操作不同的数据类型 api和我们的指令是一样的
//opsForValue 操作字符串类 类似String
//opsForList 操作List 类似List
//opsForSet
//opsForHash
//opsForGeo
//opsForZSet
//opsForHyperLogLog
//除了基本的操作,我们常用的方法都可以直接通过redisTemplate操作
//比如基本的事务和CRUD
//获取redis的连接对象
//RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
//connection.flushDb();
//connection.flushAll();
redisTemplate.opsForValue().set("mykey","xiaomi");
System.out.println(redisTemplate.opsForValue().get("mykey"));
}
}
关于对象的保存:
我们来自己编写一个RedisTemplate
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
//我们为了自己开发方便一般直接使用
// 将template 泛型设置为
RedisTemplate template = new RedisTemplate();
// 连接工厂,不必修改
template.setConnectionFactory(redisConnectionFactory);
/*
* 序列化设置
*/
// key、hash的key 采用 String序列化方式
template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());
// value、hash的value 采用 Jackson 序列化方式
template.setValueSerializer(RedisSerializer.json());
template.setHashValueSerializer(RedisSerializer.json());
template.afterPropertiesSet();
return template;
}
}
所有的redis操作,其实对于java开发人员来说,十分的简单,更重要的是理解redis的思想和每一种数据结构的用处和作用场景!
HTTP SpringCloud(生态)
RPC两个核心模块:通讯、序列化
序列化:数据传输需要转换
Netty:30天~
Dubbo~18年重启! Dubbo 3.x RPC Error Exception
专业的事,交给专业的人来做~
步骤:
1、导入相关依赖
org.apache.dubbo
dubbo-spring-boot-starter
2.7.8
com.github.sgroschupf
zkclient
0.1
org.apache.curator
curator-framework
5.1.0
org.apache.curator
curator-recipes
5.1.0
org.apache.zookeeper
zookeeper
3.6.2
org.slf4j
slf4j-log4j12
2、配置注册中心的地址,以及服务发现名,和要扫描的包
#服务应用名字
dubbo.application.name=provider-server
#注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
#哪些服务要被注册
dubbo.scan.base-packages=com.mi.service
3.在想要被注册的服务上面~增加一个注解@Service
1.导入依赖
2.配置注册中心的地址,配置自己的服务名
3.远程注入服务
三层架构 + MVC
架构 ---> 解耦
开发框架
Spring
IOC AOP
IOC:控制反转
约泡:
泡温泉,泡茶。。。。泡友
附近的人,打招呼,加微信,聊天-------->约泡
浴场:温泉,茶庄,泡友
直接进温泉,就有人和你一起了
原来我们都是自己一步步操作,现在交给容器了,我们需要什么就去拿就可以了
AOP:面向切面编程 (本质,动态代理)
为了解决什么?不影响业务本来的情况下,实现动态增加功能,大量应用在日志,事务...等等方面
Spring是一个轻量级的java开源框架,容器
目的:解决企业开发的复杂性问题
Spring是春天,觉得他是春天,也十分复杂,配置文件
SpringBoot
SpringBoot并不是新东西,就是Spring的升级版!
新一代JavaEE的开发标准,开箱即用!->拿过来就可以用!
它自动帮我们配置了非常多的东西,我们拿来即用!
特性:约定大于配置
随着公司的体系越来越大,用户越来越多
微服务架构--->新架构
模块化,功能化!
用户模块,支付模块,签到模块,娱乐模块
人过于多:一台服务器解决不了;再增加服务器!横向
假设A服务器占用98%资源,B服务器只占用了10%。---负载均衡;
将原来的整体项目,分成模块化,用户就是一个单独的项目,签到也是一个单独的项目,项目和项目之间需要通信,如何通信?
用户非常多,而签到十分少! 给用户多一点服务器,给签到少一点服务器!
微服务架构问题?
分布式架构会遇到的四个核心问题?
1. 这么多服务,客户端该如何去访问?
2. 这么多服务,服务之间如何进行通信?
3. 这么多服务,如何治理呢?
4. 服务挂了,怎么办?
解决方案:
SpringCloud,是一套生态,就是解决以上分布架构的4个问题
想使用SpringCloud,必须掌握SpringBoot,因为SpringCloud是基于SpringBoot;
1.Spring Cloud Netflix,出来了一套解决方案
Api网关,zuul组件
Feign--->HttpClient--->HTTP的通信方式,同步并阻塞
服务注册与发现,Eureka
熔断机制,Hystrix
2018年年底,Netflix宣布无限期停止维护。生态不再维护,就会脱节。
2.Apache Dubbo zookeeper,第二套解决系统
Api:没有!要么找第三方插件,要么自己实现
Dubbo是一个高性能的基于Java实现的,RPC通信框架!
服务注册与发现,zookeeper:动物园管理者(Hadoop,Hive)
没有:借助了Hystrix
不完善,Dubbo
3. SpringCloud Alibaba 一站式解决方案
目前,又提出了一种方案:
服务网格:下一代微服务标准。Server Mesh
代表解决方案:Istio
万变不离其宗,一通百通
1.API网关,服务路由
2.HTTP,RPC框架,异步调用
3.服务注册与发现,高可用
4.熔断机制,服务降级
如果,你们基于这四个问题,开发一套解决方案,也叫SpringCloud!
为什么要解决这个问题?本质:网络不可靠
程序员,不能停下学习的脚步
三层架构 + MVC
架构 ---> 解耦
开发框架
Spring
IOC AOP
IOC:控制反转
约泡:
泡温泉,泡茶。。。。泡友
附近的人,打招呼,加微信,聊天-------->约泡
浴场:温泉,茶庄,泡友
直接进温泉,就有人和你一起了
原来我们都是自己一步步操作,现在交给容器了,我们需要什么就去拿就可以了
AOP:面向切面编程 (本质,动态代理)
为了解决什么?不影响业务本来的情况下,实现动态增加功能,大量应用在日志,事务...等等方面
Spring是一个轻量级的java开源框架,容器
目的:解决企业开发的复杂性问题
Spring是春天,觉得他是春天,也十分复杂,配置文件
SpringBoot
SpringBoot并不是新东西,就是Spring的升级版!
新一代JavaEE的开发标准,开箱即用!->拿过来就可以用!
它自动帮我们配置了非常多的东西,我们拿来即用!
特性:约定大于配置
随着公司的体系越来越大,用户越来越多
微服务架构--->新架构
模块化,功能化!
用户模块,支付模块,签到模块,娱乐模块
人过于多:一台服务器解决不了;再增加服务器!横向
假设A服务器占用98%资源,B服务器只占用了10%。---负载均衡;
将原来的整体项目,分成模块化,用户就是一个单独的项目,签到也是一个单独的项目,项目和项目之间需要通信,如何通信?
用户非常多,而签到十分少! 给用户多一点服务器,给签到少一点服务器!
微服务架构问题?
分布式架构会遇到的四个核心问题?
1. 这么多服务,客户端该如何去访问?
2. 这么多服务,服务之间如何进行通信?
3. 这么多服务,如何治理呢?
4. 服务挂了,怎么办?
解决方案:
SpringCloud,是一套生态,就是解决以上分布架构的4个问题
想使用SpringCloud,必须掌握SpringBoot,因为SpringCloud是基于SpringBoot;
1.Spring Cloud Netflix,出来了一套解决方案
Api网关,zuul组件
Feign--->HttpClient--->HTTP的通信方式,同步并阻塞
服务注册与发现,Eureka
熔断机制,Hystrix
2018年年底,Netflix宣布无限期停止维护。生态不再维护,就会脱节。
2.Apache Dubbo zookeeper,第二套解决系统
Api:没有!要么找第三方插件,要么自己实现
Dubbo是一个高性能的基于Java实现的,RPC通信框架!
服务注册与发现,zookeeper:动物园管理者(Hadoop,Hive)
没有:借助了Hystrix
不完善,Dubbo
3. SpringCloud Alibaba 一站式解决方案
目前,又提出了一种方案:
服务网格:下一代微服务标准。Server Mesh
代表解决方案:Istio
万变不离其宗,一通百通
1.API网关,服务路由
2.HTTP,RPC框架,异步调用
3.服务注册与发现,高可用
4.熔断机制,服务降级
如果,你们基于这四个问题,开发一套解决方案,也叫SpringCloud!
为什么要解决这个问题?本质:网络不可靠
程序员,不能停下学习的脚步
B站地址:https://space.bilibili.com/95256449