什么是SpringBoot

微服务架构风格(microservice architectural style)的出现:把应用程序构建为一套服务。

事实是,服务可以独立部署和扩展,每个服务提供了一个坚实的模块边界,甚至不同的服务可以用不同的编程语言编写。它们可以被不同的团队管理。

coc:约定大于配置,也称作按约定编程,是一种软件设计规范,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。

Spingboot给对象赋值

  • 自动注入

    • 类上声明@Compoent
    • 属性上@AutoWore("");
  • yaml赋值

    • yaml文件中写入类
    • 类上声明@ConfigurationProperties( prefix = "yaml的类名");
  • properties

    • 类上声明@PropertiesSource
    • 逐个在属性上@Value("${属性名})

JSR303校验:

  • 判断是否符合格式

  • 类上方@Validated

  • 类属性上@Email是判断是否符合邮箱格式

自动装配原理

  • SpringBoot启动会加载大量的自动配置类

  • 我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

  • 我们在来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在其中,

我们就不需要在手动配置了)

  • 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

  • xxxAutoConfiguration:自动配置类;给容器中添加组件

  • xxxProperties:封装配置文件中的相关属性

静态资源访问:

在springboot,我们可以使用一下 方式处理静态资源

1. webjarslocalhost:8080/webjars
2. public ,static,resourcelocalhost:8080/

优先级:resource>static(默认)>public

设定首页:

​ index首页放在静态资源区会自动扫面到

​ 图标定制在新版本中被取消了,可以用link标签

<link rel="shortcut" href="">

Thymeleaf模板引擎

使用步骤:

  • 1.pom.xml中添加依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 2.中添加导入约束

    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    
  • 3.使用thymeleaf语法获取参数

    <!-- >获取参数  -->
    <div th:text = "${msg}"></div>
    
    <!-- 获取不转义参数 -->
    <div th:utext = "${msg}"></div>
    
    <!-- 循环遍历数组 -->
    <h3 th:each="user:${users}" th:text="${user}"></h3>
    
    <!-- 不推荐使用  -->
    <h3 th:each="user:${users}" >[[${user}]]</h3>
    
    <!--  link 引入资源标签 src前面加上th:   路径用@{/} /是指resource根目录下-->
    <link th:href="@{/static/login.css}">
    
    <!-- 
    	a标签给controller传值 
    	controller层:
    		@ReQuestMapping("/production/{proid}")
    		public String product(@PathVariable(name = "proid")int proid,){                
     		}
    -->
    <a th:href="@{'/prodction/'+${production.id}}" th:text="${production.title}">XXX</a>
    
    

页面改变之后前端未发生变化

配置文件中加入

service.themeleaf.cache=false
@Bean

public ViewResolver myViewResolver(){

return new MyViewResolver();

}

public static class MyViewResolver implements ViewResolver{

@Override

public View resolveViewName(String viewName, Locale locale) throws Exception {

return null;

}

}

自定义一个视图解析器

1.java目录下新建一个包config新建myMvcConfig实现类

2.类上声明@configuration,并实现WebMvcConfigurer接口

3.自定义一个静态类实现viewResoler接口,重写resolveViewName方法

4.@Bean声明一个bean标签,实现就试图截器器的接口类

5.return 视图截器器

设定主页时** 😗*

在myMvcConfig实现类中重写一个addViewControllers(ViewControllerRegistry registry)方法

public void addViewControllers(ViewControllerRegistry registry){

	registry.addViewController(&quot;/&quot;,setViewName(&quot;index&quot;);

	registry.addViewController(&quot;/index.html&quot;,setViewName(&quot;index&quot;);

}

页面登录成功重定向,隐藏传递参数

控制器类中返回的值时String时,return "redirect:/main.html";

在视图webmvc配置类中添加视图解析

registry.addViewController("/main.html",setViewName("html的页面名称");

SpringBoot解决@ResponseBody中文乱码问题

在@RequestMapping中设置格式

@RequestMapping(value = "/XXX/xxx", produces = "application/json; charset=utf-8")

登录拦截设置

1)新建一个HandlerInterceptor的实现类,重写preHandle方法,判断session中是否有值

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

//登录之后,应该有用户的session

Object loginUser = request.getSession().getAttribute(&quot;username&quot;);

	if(loginUser == null){

	request.setAttribute(&quot;msg&quot;,&quot;没有权限,请先登录&quot;);

	//下方错误待处理

	request.getRequestDispatcher(&quot;/toLogin&quot;).forward(request,response);

	return false;

	}else {

		return true;

	}
}

2)webmvc配置类中添加拦截器,重写addInterceptors方法和addResourceHandlers方法

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
            .excludePathPatterns("/index.html","/","/toLogin","/userlogin","/registered","/css/*","/js/**","/font/**","/image/**","/layui.js");

}

Thymeleaf 中前端代码组件化

在相应的div中加入一个属性,th:fragmeng="唯一标识名"

在对应的html中加入div,并添加属性th:insert="~{标识符}"

SpringBoot** 整合 jdbc (在构建项目时引入 jdbc 的 **** API **** 和 **** mysql Driver **

  1. 在配置文件(application.yml)中声明spring.datasource.username / password / url / driver-class-name,

在url后面加入useUnicode=true&characterEncoding=utf-8,

如果出现时区报错了,就在url后面加入&serverTimezone=UTC

  1. 在Controller类中自动注入jdbcTheplate

  2. 首先sql语句,使用jdactheplate中的query / update进行数据操作

SpringBoot整合Durid

(在构建项目时引入jdbc 的 API 和 mysql Driver )

使用步骤

1)在pom文件中加入druid依赖和log4j依赖

<!-- druid 依赖 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.9</version>
</dependency>
<!-- log4j 依赖-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2)在配置文件中声明datasource类型为druid,并赋值一些属性

数据源基本配置

#   数据源基本配置
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/duid
#    声明数据源类型
    type: com.alibaba.druid.pool.DruidDataSource
#   数据源其他配置
    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,去掉后监控界面sql无法统计,'wall'用于防火墙  
#    stat:监控统计 wall:防止sql注入 log4j:日志记录
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true  
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

3)在config包下新建配置类(JDBCController)

/**
     *@return 返回监控注册的servlet对象
     * @author SimpleWu
     */
     
     //再类上方声明@configuration
     //写方法返回Druid
     @Bean
     @Configurationproperties( prefix = "spring.datasource")
     public DataSource druidDataSource(){
         return new DruidDataSource();     
     }
     //配置监控服务器
    @Bean
    public ServletRegistrationBean statViewServlet() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
        // 添加IP白名单
        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        // 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
        servletRegistrationBean.addInitParameter("deny", "127.0.0.1");
        // 添加控制台管理用户 名称固定不可出错
        servletRegistrationBean.addInitParameter("loginUsername", "SimpleWu");
        servletRegistrationBean.addInitParameter("loginPassword", "123456");
        // 是否能够重置数据
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }

    /**@return 返回过滤器配置对象
     */
     * 配置服务过滤器
     *
     * 
    @Bean
    public FilterRegistrationBean statFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        // 添加过滤规则
        filterRegistrationBean.addUrlPatterns("/*");
        // 忽略过滤格式
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*,");
        return filterRegistrationBean;
    }
    


springboot 整合 mybatis

使用步骤

  1. 导入mybatis spring boot starter依赖

  2. 在配置文件(application.yml)中声明spring.datasource.username / password / url / driver-class-name,

    再声明mybatis.type-aliases-package=com.kuang.pojo,mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

  3. 新建pojo包新建mysql类新建mapper包下mapper类,(类上声明@Mapper/在springboot05MybatisApplication上声明注解@MapperScan(com.kuang.mapper&

    quot;),并在类上声明@Repository持节类注解,在类中声明方法

  4. 在resource下新建包mybatis.mapper

  5. 在controller中调用service使用

SpringBoot 整合SpringSecurity(安全框架)

作用:省去拦截器过滤器的繁琐,直接使用框架重写继承类方法

"这个登录并不是自己写的登录页面,而是security生成的登录页面

使用步骤

1)pom文件引入thymeleaf和springsecurity依赖

2)在config中新建SecurityConfig,在类上方加入@EnableWebSecurity

3)类继承 WebSecurityConfigurerAdapter,并重写void configure(HttpSecurity http)方法

//在该方法中授权,首页可以任何人访问,功能页只有有对应的权限才能访问
http.authorizeRequests()
    .antMatchers("/").permitALl()
    .antMatcher("/level1/**").hasRoler("vip1")
    .antMatcher("/level2/**").hasRoler("vip2")
    .antMatcher("/level3/**").hasRoler("vip3")
    
//没有权限会默认到登录页面
//定制登录页 默认后面属性为username,password,不同时需要自己设定,后面的action同理
http.formLogin().loginPage("toLogin").usernameParamter("user").passwordParamter("pwd").loginProcessingUrl("login");

//防止网站工具 get,post
//关闭csrf功能,登录失败存在的原因
http.csrf().disable();
//注销.开启了注销功能,跳到首页
http.logout().logoutSuccessUrl("/");

//开启记住我 cookie默认保存两周 自定义的记住我
http.rememberMe().rememberMeparameter("remember");

4)类中重写void configure(AuthenricationManagerBuilder auth) 方法,对不同用户进行授权

//对不同用户进行认证,并将密码新建加密方式
auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoding())
    .withUser("kuangshen").password(new BCryptPasswordEncoding().encode("123456")).role("vip2","vip3")
    .and()
    .withUser("root").password(new BCryptPasswordEncoding().encode("123456")).role("vip1","vip2","vip3")
    .and()
    .withUser("guest").password(new BCryptPasswordEncoding().encode("123456")).role("vip1")

5)在依赖中加入thymeleaf和security的整合包依赖,只要在页面上导入命名空间

xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity4"

就可以在html中进行权限判断,以此显示不同的页面

<!-- security-thymeleaf整个包 -->
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity4</artifactId>
    <version>3.0.4.RELEASE</version>
</dependency>

sec:authorize="hasRole('vip'1)"是否有相应的权限,反之前加!

sec:authentication="name"获取登录的名字

sec:authorize="isAuthenticated()"是否已经登录,反之前加!

shrio 快速使用

Apache Shiro 是 Java 的一个安全框架。

  • Authentication:身份认证 / 登录,验证用户是不是拥有相应的身份;

  • Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限;

  • Session Management :会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的;

  • Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

  • Web Support:Web 支持,可以非常容易的集成到 Web 环境;

  • Caching:缓存,比如用户登录后,其用户信息、拥有的角色 / 权限不必每次去查,这样可以提高效率;

  • Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去;

  • Testing:提供测试支持;

  • Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问;

  • Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

![屏幕截图 2022-04-12 232641](F:\typera\boke\Springboot\屏幕截图 2022-04-12 232641.png)

  • Subject :主体,代表了当前 "用户",这个用户不一定是一个具体的人,与当前应用交互的任何东西都是 Subject,如网络爬虫,机器人等;即一个抽象概念;所有 Subject 都绑定到 SecurityManager,与 Subject 的所有交互都会委托给 SecurityManager;可以把 Subject 认为是一个门面;SecurityManager 才是实际的执行者;

  • SecurityManager :安全管理器;即所有与安全有关的操作都会与 SecurityManager 交互;且它管理着所有 Subject;可以看出它是 Shiro 的核心,它负责与后边介绍的其他组件进行交互,如果学习过 SpringMVC,你可以把它看成 DispatcherServlet 前端控制器;

  • Realm :域,Shiro 从 Realm 获取安全数据(如用户、角色、权限),就是说 SecurityManager 要验证用户身份,那么它需要从 Realm 获取相应的用户进行比较以确定用户身份是否合法;也需要从 Realm 得到用户相应的角色 / 权限进行验证用户是否能进行操作;可以把 Realm 看成 DataSource,即安全数据源。

记住一点, Shiro 不会去维护用户、维护权限;这些需要我们自己去设计 / 提供;然后通过相应的接口注入给 Shiro 即可。

Shiro的优点:

简单的身份认证, 支持多种数据源

对角色的简单的授权, 支持细粒度的授权(方法级)

支持一级缓存,以提升应用程序的性能;

内置的基于 POJO 企业会话管理, 适用于 Web 以及非 Web 的环境

非常简单的加密 API

不跟任何的框架或者容器捆绑, 可以独立运行

Shiro 架构 核心组件:

  • Authenticator:管理登陆登出

  • Authorizer:授权器赋予主体有那些权限

  • session Manager:shiro自己实现session管理器

  • session DAO:提供了session的增删改插

  • Cache Manager:缓冲管理器

  • Raelms:和数据库交互的桥梁

shiro认证过程:

创建SecurityManager --> 主体提交认证 --> SecurityManager认证–> Authenticator认证–> Realm验证

shiro 授权过程:

创建SecurityManager -->主体授权 --> securityManager授权 --> Authorizer授权 --> Realm获取权限数据

1)导入依赖

<!-- shiro 依赖 -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring</artifactId>
    <version>1.4.1</version>
</dependency>

2)config先新建类Shiro类

@Configuration
public class ShiroController {
    //创建ShiroFilterFactoryBean关联DefaultWebSecurityManager
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(@Qualifier("SecurityManager")DefaultWebSecurityManager defaultWebSecurityManager){
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        bean.setSecurityManager(defaultWebSecurityManager);
        //添加shiro的内置过滤器
        /*
            anon:无需认证就可访问
            authc:必须认证了才能访问
            user:必须拥有 记住我 功能才可以访问
            perms:拥有对某个资源的权限才能访问
            role:拥有某个角色权限才能访问

         */
        Map<String,String> filterMap = new LinkedHashMap<>();
        filterMap.put("/toLook","authc");
        bean.setFilterChainDefinitionMap(filterMap);
        bean.setLoginUrl("/toLogin");
        return bean;
    }

    //创建DefaultWebSecurityManager关联UserRealm
    @Bean(name = "SecurityManager")
    public DefaultWebSecurityManager dafaultWebSecurityManager(@Qualifier("userRealm") UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        return securityManager;
    }
    //创建realm对象
    @Bean
    public UserRealm userRealm(){
        return new UserRealm();
    }
}

3)同时在config下新建UserReal

//自定义的UserRealm
public class UserRealm extends AuthorizingRealm {

    @Autowired
    UserinfoService userinfoService;
    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("授权");
        return null;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("认证");

        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
        List<Userinfo> userinfos = userinfoService.selectByUsername(userToken.getUsername());

        if(userinfos.isEmpty()){
            return null;
        }
        Userinfo userinfo = userinfos.get(0);
        //密码认证
        return new SimpleAuthenticationInfo("",userinfo.getPassword(),"");
    }
}

Swagger 的使用

前端测试框架

前些年前后端交互性太差,没有及时交流,当前端进行数据修改时,后端改动较大

最流行Api:swagger

使用步骤(** Swagger2 **** 中 2.X.X 依赖)**

1)新建Springboot web项目

2)导入依赖

  • swagger2
  • ul
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>3.0.0</version>
</dependency>

  1. 在config包下新建SwaggerConfig
@Configuration

@EnableSwagger2 //开启swagger

public class SwaggerConfig {

}

4)/swagger-ui.html已经新访问页面

使用步骤( swagger2 3.0.0 依赖)

1.新建springboot-web项目

2.导入依赖

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>3.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-ui</artifactId>
    <version>3.0.0</version>
</dependency>

3.在config包下新建SwaggerConfig

@Configuration
@EnableWebMvc
public class SwaggerConfig {
    @Bean
    public Docket createRestApi(){
        return new Docket(DocumentationType.SWAGGER_2) //指定api类型为swagger2
                .apiInfo(apiInfo())   //定义api文档配置信息
                .select().apis(RequestHandlerSelectors.basePackage("com.my.controller"))  //指定需要扫描的controller包
                .paths(PathSelectors.any())         //所有 xxxController都需要生成
                .build();
    }

    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("Swagger接口API文档")                   //文档页标题
                .contact(new Contact("郭远","www.baidu.com","123456@qq.com"))        //联系人信息
                .description("api文档的描述")
                .version("1.0")             //文档版本号
                .termsOfServiceUrl("https://www.shixin.com")   //网站地址
                .build();

    }
}

4.在/swagger-ui/index.html访问

分组问题

通过创建多个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");
}

api 注释

  1. Api@Api 用在类上,说明该类的作用。

  2. ApiModel@ApiModel 用在类上,表示对类进行说明,用于实体类中的参数接收说明。

  3. ApiModelProperty@ApiModelProperty() 用于字段,表示对 model 属性的说明。

  4. ApiParam@ApiParam 用于 Controller 中方法的参数说明。

  5. ApiOperation@ApiOperation 用在 Controller 里的方法上,说明方法的作用,每一个接口的定义。

  6. ApiResponse 和 ApiResponses@ApiResponse 用于方法上,说明接口响应的一些信息

  7. ApiImplicitParam 和 ApiImplicitParams用于方法上,为单独的请求参数进行说明。

常见的处理方式

异步处理

在启动类上,加入@EnableAsync

在Service的方法上加入@Async

邮箱处理

使用步骤:

1)加入邮箱依赖

<!-- 邮箱依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

2)在service中调用

@Autowired
JavaMailSenderImpl mailSender;

//一个简单的邮件发送
@Test
void t1(){
    SimpleMailMessage mailMessage = new SimpleMailMessage();
    mailMessage.setSubject("测试文件");
    mailMessage.setText("测试内容,无需回复!");
    mailMessage.setTo("2576709493@qq.com");
    mailMessage.setFrom("xiaoyuyunnote@163.com");
    mailSender.send(mailMessage);
}

//一个复杂的的邮件发送
@Test
void t2() throws MessagingException {
    MimeMessage mailMessage = mailSender.createMimeMessage();
    //组件
    MimeMessageHelper helper = new MimeMessageHelper(mailMessage, true);

    helper.setSubject("测试文件");
    // true表示启用html格式
    helper.setText("<p style='color:red'>测试发送附件</p>",true);

    //附件
    helper.addAttachment("1.jpg",new File("C:\\Users\\gy\\Pictures\\Camera Roll\\home1.jpg"));

    helper.setTo("2576709493@qq.com");
    helper.setFrom("xiaoyuyunnote@163.com");
    mailSender.send(mailMessage);
}

异步处理

使用步骤

1)在启动类上加入@EnableScheduling

2)在service类中使用,方法上声明@Scheduled("")

cron表达式,六个值 (秒,分,时,日,月,星期)

  • :: 表示匹配该域的任意值。比如Minutes域使用*,就表示每分钟都会触发。
  • -:表示范围。比如Minutes域使用 10-20,就表示从10分钟到20分钟每分钟都会触发一次。

  • ,:表示列出枚举值。比如Minutes域使用1,3,就表示1分钟和3分钟都会触发一次。

  • / : 表示间隔时间触发(开始时间/时间间隔)。例如在Minutes域使用 5/10,就表示从第5分钟开始,每隔10分钟触发一次。

  • ? : 表示不指定值。简单理解就是忽略该字段的值,直接根据另一个字段的值触发执行。

  • 表示该月第n个星期x(x#n),仅用星期域。如:星期:6#3,表示该月的第三个星期五。

  • L : 表示最后,是单词"last"的缩写(最后一天或最后一个星期几);仅出现在日和星期的域中。用在日则表示该月的最后一天,用在星期则表示该月的最后一个星期。如:星期域上的值为5L,则表示该月最后一个星期的星期四。在使用'L'时,不要指定列表','或范围'-',否则易导致出现意料之外的结果。

  • W: 仅用在日的域中,表示距离当月给定日期最近的工作日(周一到周五),是单词"weekday"的缩写。

Dubbo+Zookeeper集成分布式项目

Dubbo是一款由阿里巴巴开发的远程服务调用框架(RPC),其可以透明化的调用远程服务,就像调用本地服务一样简单。截至目前,Dubbo发布了基于Spring Boot构建的版本,版本号为0.2.0,这使得其与Spring Boot项目整合变得更为简单方便。而Zookeeper在这里充当的是服务注册中心的角色,我们将各个微服务提供的服务通过Dubbo注册到Zookeeper中,然后服务消费者通过Dubbo从Zookeeper中获取相应服务并消费。

![截图 (1)](F:\typera\boke\Springboot\截图 (1).png)

使用步骤

1)启动 zookeeper 注册中心:

在搭建项目之前需要启动 Zookeeper 服务,Zookeeper官方下载地址:http://zookeeper.apache.org/releases.html#download

下载后解压,将config目录下的zoo_sample.cfg 重命名为 zoo.cfg (Zookeeper配置文件,默认端口为2181,可根据实际进行修改)。然后双击bin目录下的zkServer.cmd启动即可。

(个人感觉每次运行项目都要启动 zookeeper,麻烦,看这篇文章设置开机自启:Windows下把ZooKeeper注册成为Windows服务,实现开机自启动

2)构建项目

新建maven或者springboot项目

3)环境配置

privider-server 接口提供者

1.导入依赖

<!--导入依赖-->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.3</version>
        </dependency>

        <!--zkclient-->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>

        <!--解决日志冲突-->
        <!--引入zookeeper-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>
        <!--解决 java.lang.NoClassDefFoundError: org/apache/curator/framework/recipes/cache/TreeCacheListener-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.14</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

2.配置文件

# 服务端口
server.port=8001
# 注册服务应用名字
dubbo.application.name=provider-server
# 注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181
# 哪些服务需要被注册
dubbo.scan.base-packages=com.xiao.service

3.写service层

​ 在实现类中加入dubbo中的@service注解,加入@Component

4.启动项目(该项目必须是配置好log4j配置文件的,否则会报错)

consumer-server 接口消费者

1.导入依赖

        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.7.3</version>
        </dependency>

        <!--zkclient-->
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>

        <!--解决日志冲突-->
        <!--引入zookeeper-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>2.12.0</version>
        </dependency>
        <!--解决 java.lang.NoClassDefFoundError: org/apache/curator/framework/recipes/cache/TreeCacheListener-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.14</version>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

2.配置文件

# 服务端口
server.port=8002
# 消费者取哪里拿服务需要暴露自己的名字
dubbo.application.name=consumer-server
# 注册中心地址
dubbo.registry.address=zookeeper://127.0.0.1:2181

3.log4j.properties配置文件

4.写service层,

​ 写下和接口提供者service相同的接口层

​ 在实现类中,使用Duboo中的@Reference注解自动注入service类

4) dubbo-admin 管理控制台部署

1.修改 dubbo.properties文件 如下:

截图

2**.**把 dubbo-admin 打包成 jar 包然后 java -jar 运行 jar包 即可

3.访问 http://localhost:7001/ 进入管理界面:

5).启动运行 privider-server 和 consumer-server

1.先启动 privider-server

2.查看 dubbo-admin 可以看到 privider-server 已把业务层接口发布到注册中心

3.测试消费者是否远程调用到了接口:

文章作者: 郭远
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 郭远的博客空间
SpringBoot SpringBoot
喜欢就支持一下吧
打赏
微信 微信
支付宝 支付宝