JavaSE:OOP
MySQL:持久化
HTML+CSS+JS+jQuery+框架:视图,框架不熟练,CSS不好
Javaweb:独立开发MVC三层架构的网站
SSM:框架 简化了开发流程 配置也开始较为复杂
Spring Boot基于Spring 开发,Spirng Boot本身并不提供Spring框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring框架的应用程序。也就是说,它并不是用来替代Spring 的解决方案,而是和Spring框架紧密结合用于提升Spring 开发者体验的工具。SpringBoot以约定大于配置的核心思想,默认帮我们进行了很多设置,多数Spring Boot应用只需要很少的Spring 配置。同时它集成了大量常用的第三方库配置(例如Redis、MongoDB、Jpa、RabbitMQ、Quartz等等),Spring Boot应用中这些第三方库几乎可以零配置的开箱即用。
简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包, spring boot整合了所有的框架。
Spring Boot的主要优点:
微服务是一种架构风格,它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合;可以通过http的方式进行互通。要说微服务架构,先得说说过去我们的单体应用架构。
所谓单体应用架构(all in one)是指,我们将一个应用的中的所有应用服务都封装在一个应用中。
无论是ERP、CRM或是其他什么系统,你都把数据库访问,web访问,等等各个功能放到一个war包内。
all in one的架构方式,我们把所有的功能单元放在一个应用里面。然后我们把整个应用部署到服务器上。如果负载能力不行,我们将整个应用进行水平复制,进行扩展,然后在负载均衡。
所谓微服务架构,就是打破之前all in one的架构方式,把每个功能元素独立出来。把独立出来的功能元素的动态组合,需要的功能元素才去拿来组合,需要多一些时可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而没有对整个应用进行复制。
这样做的好处是:
1.节省了调用资源。
2.每个功能元素的服务都是一个可替换的、可独立升级的软件代码。
一个大型系统的微服务架构,就像一个复杂交织的神经网络,每一个神经元就是一个功能元素,它们各自完成自己的功能,然后通过http相互请求调用。比如一个电商系统,查缓存、连数据库、浏览页面、结账、支付等服务都是一个个独立的功能服务,都被微化了,它们作为一个个微服务共同构建了一个庞大的系统。如果修改其中的一个功能,只需要更新升级其中一个功能服务单元即可。
但是这种庞大的系统架构给部署和运维带来很大的难度。于是,spring为我们带来了构建大型分布式微服务的全套、全程产品:
pom.xml
spring-boot-dependencies在父工程中存放核心依赖
启动器
org.springframework.boot
spring-boot-starter
主程序
//@SpringBootApplication:标注这个类是一个spring boot的应用 启动类下的所有被导入
@SpringBootApplication
public class HelloworldApplication {
public static void main(String[] args) {
//将spring boot启动起来 通过反射
SpringApplication.run(HelloworldApplication.class, args);
}
}
@SpringBootConfiguration:springboot的配置
@Configuration:spring配置类
@Component:说明这也是一个spring的组件
@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;
}
protected Class> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
META-INF/spring.factories:自动配置的核心文件
流程图:自动配置原理分析 | ProcessOn免费在线作图,在线流程图,在线思维导图
结论:SpringBoot所有自动配置都是在启动的时候扫描并加载:spring.factories所有的自动配置类都在这里面,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器,有了启动器,自动装配就会生效,就配置成功。
//@SpringBootApplication:标注这个类是一个spring boot的应用
@SpringBootApplication
public class HelloworldApplication {
public static void main(String[] args) {
//将spring boot启动起来 通过反射
SpringApplication.run(HelloworldApplication.class, args);
}
}
最初以为就是运行了一个main方法,没想到却开启了一个服务;
SpringApplication.run分析
分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;
这个类主要做了以下四件事情
关于SpringBoot,谈谈你的理解:
SpringBoot使用一个全局的配置文件,配置文件名称是固定的.
配置文件的作用︰修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;
可以直接给实体类赋值
application.yml和spring.factories的联系
//表示这是一个配置类
@Configuration(proxyBeanMethods = false)
//自动配置属性: HttpProperties
@EnableConfigurationProperties
//Spring的底层注解: 根据不同的条件 来判断当前配置或者类是否生效
@ConditionalOnWebApplicatioin(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding",value = "enabled",matchIfMissing = true)
精髓:
1) 、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;
3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;
xxxxAutoConfigurartion:自动配置类;给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
总结:
factory.ico
thymeleaf
结论:只要需要使用thymeleaf,只需要导入对应的依赖就可以了,将html放在templates目录下即可。
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
自定义视图解析器
//如果 你想diy一些定制化的功能 只要写这个组件 然后将它交给spring boot ,spring boot就会帮我们自动装配
//扩展 springmvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
// public interface ViewResolver 实现了视图解析器接口的类 我们就可以把它看做视图解析器
@Bean
public ViewResolver myViewResolver(){
return new MyViewResolver();
}
//自定义一个自己的视图解析器MyViewResolver
private class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String viewName, Locale locale) throws Exception {
return null;
}
}
}
在springboot中,有非常多的XXX Configuration帮助我们进行扩展配置,只要看见这个,就需要注意。
前端:
Druid
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
//后台监控:web.xml 死代码 直接使用
//因为Springboot内置了servlet容器 所以没有web.xml
@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","localhost");
//禁止谁能访问
bean.setInitParameters(initParameters); //设置初始化参数
return bean;
}
//filter
public FilterRegistrationBean webStatFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
//可以过滤哪些请求
HashMap initParameters = new HashMap<>();
//这些东西不进行统计
initParameters.put("exclusions","*.js,*.css,/druid/*");
return bean;
}
}
数据源配置
type: com.alibaba.druid.pool.DruidDataSource
#SpringBoot默认是不注入这些属性的 需要自己绑定
#druid 数据源专有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuert: SELECT 1 FROM DUAL
testwhileIdle: false
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
整合包
mybatis-spring-boot-starter
在web开发中,安全第一位。过滤器,拦截器
非功能性需求
做网站:安全应该在什么时候考虑?设计之初
从外部看Shiro,即从应用程序角度来观察如何使用shiro完成工作:
学习目标:
Vue + SpringBoot
后端时代:前端只用管理静态页面;HTML==》后端,模板引擎JSP
前后端分离时代:
产生一个问题:
解决方案:
Swagger
官网:API Documentation & Design Tools for Teams | Swagger
在项目中使用Swagger需要Springfox;
io.springfox
springfox-swagger2
3.0.0
io.springfox
springfox-swagger-ui
3.0.0
@Configuration
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
}
Swagger的bean实例Docket;
@Configuration
@EnableSwagger2 //开启Swagger2
public class SwaggerConfig {
//配置了Swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}
//配置Swagger信息 ==》 apiInfo
private ApiInfo apiInfo(){
//作者信息
Contact contact = new Contact("hzx","http://localhost:8080","[email protected]");
return new ApiInfo(
"hzx的SwaggerAPI文档",
"即使再小的帆也能远航",
"1.0",
"http://localhost:8080",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}
}
Docket.select()
//配置了Swagger的Docket的bean实例
@Bean
public Docket docket(){
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//RequestHandlerSelectors配置要扫描接口的方式
//basePackage指定要扫描的包
//any() 扫描全部
//none 都不扫描
//withclassAnnotation 扫描类上的注解 参数是一个注解的反射对象
//withMethodAnnotation 扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.hzx.controller"))
//paths 过滤什么路径
.paths(PathSelectors.ant("/hzx/**"))
.build();
}
docket里有enable 设置为false 不启动
我只希望我的Swagger在生产环境中使用,在发布的时候不适用?
@Bean
public Docket docket(Environment environment){
//设置要显示的Swagger环境
Profiles profiles = Profiles.of("dev","test");
//获取项目环境 通过environment.acceptsProfiles判断环境
boolean b = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//enable是否启动Swagger 如果为false 则Swagger不能在浏览器中访问
.enable(b)
.select()
//RequestHandlerSelectors配置要扫描接口的方式
//basePackage指定要扫描的包
//any() 扫描全部
//none 都不扫描
//withclassAnnotation 扫描类上的注解 参数是一个注解的反射对象
//withMethodAnnotation 扫描方法上的注解
.apis(RequestHandlerSelectors.basePackage("com.hzx.controller"))
//paths 过滤什么路径
// .paths(PathSelectors.ant("/hzx/**"))
.build();
}
.groupName("hzx")
如何配置多个分组?多个Docket实例即可
@Bean
public Docket docket1(){
return new Docket(DocumentationType.SWAGGER_2).groupName("a1");
}
@Bean
public Docket docket2(){
return new Docket(DocumentationType.SWAGGER_2).groupName("a2");
}
@Bean
public Docket docket3(){
return new Docket(DocumentationType.SWAGGER_2).groupName("a3");
}
//@Api(注释)
@ApiModel("用户实体类")
public class User {
@ApiModelProperty("用户名")
public String username;
@ApiModelProperty("密码")
public String password;
}
异步任务~@Async
定时任务~@Scheduled
邮件发送~
public void sendMail() throws MessagingException {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setSubject("你好啊");
mimeMessageHelper.setText("1111
",true);
mimeMessageHelper.addAttachment("1.jpg",new File(""));
mimeMessageHelper.setTo("[email protected]");
mimeMessageHelper.setFrom("[email protected]");
mailSender.send(mimeMessage);
}
在《分布式系统原理与范型》一书中有如下定义:“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”;
分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
分布式系统(distributed system)是建立在网络之上的软件系统。
首先需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。因为,分布式系统要解决的问题本身就是和单机系统一样的,而由于分布式系统多节点、通过网络通信的拓扑结构,会引入很多单机系统没有的问题,为了解决这些问题又会引入更多的机制、协议,带来更多的问题。。。
RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。为什么要用RPC呢?就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。RPC就是要像调用本地的函数一样去调远程函数;
RPC两个核心模块:通信、序列化
Apache Dubbo |'dxbeu|是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
步骤:
前提:zookeeper服务已开启
学习Java关注狂神说