spring boot入门篇

一、大背景 聊聊微服务

微服务是服务化思路的一种最佳实践方向,遵循SOA的思路,各个企业 在服务化治理的道路上走的时间长了,踩的坑多了,整个软件交付链路上各个环节的基础设施逐渐成熟了,微服务自然而然就诞生了。
          之所以叫微服务,是与之前的服务化思路和实践相比较而来的。早些年的服务实现和实施思路是将很多功能从开发到交付都打包成一个很大的服务单元(一般称为monolith),而微服务实现和实施思路则更强调功能趋向单一,服务单元小型化和微型化。
         从思路和理念上讲,微服务就是倡导大家尽量将功能进行拆分,将服务粒度做小,使之可以独立承担对外服务的职责,沿着这个思路开发和交付的软件服务实体,就叫作“微服务”,而围绕这个思路和理念构建的一系列基础设施和指导思想,我们称之为“微服务体系”。

微服务带来的好处
1、独立:
功能单一:各服务基本是独立的项目;
团队独立:可以保证微服务的并行研发,并且快速迭代;
运行独立:具有强大的可扩展性;
2、多语言生态:
微服务独立之后,给了对应的团队和组织快速迭代和交付的能力,同时,也给团队和组织带来了更多的灵活性,实际上,对应交付不同微服务的团队或者组织来说,现在可以基于不同的计算机语言生态构建这些服务。
微服务的提供者既可以使用Java或者Go等静态语言完成微服务的开发和交付,也可以使用Python或者Ruby等动态语言完成微服务的开发和交付,对于团队内部拥有繁荣且有差异的语言文化来说,多语言生态下的微服务开发和交付将可以最大化地发挥团队和组织内部各成员的优势。


spring boot
springBoot微框架实际上就是为JAVA语言生态而生的一种微服务最佳实践。

二、饮水思源 spring框架的本质

springBoot框架的命名关键在“boot”上,或许Boot Spring更能说明这个微框架设计的初衷,也就是快速启动一个spring应用。
          spring框架的基本概念:
          IoC(Inversion Of Control):传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建。
         DI(Dependency Injection):即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。
         AOP(Aspect Oriented Programming):即面向切面编程。面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP与OOP是面向不同领域的两种设计思想。OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

JavaConfig
当Java5推出基于纯Java Annotation的依赖注入框架Guice时,spring框架也推出了基于Java代码和Annotation元信息的依赖关系绑定描述方式,JavaConfig。
基于JavaConfig方式的依赖关系绑定描述基本上映射了最早的基于XML的配置方式。例如:
xml配置方式:<bean id=”myTest” class=”...MyTest”>...</bean>
JavaConfig配置方式:
@Configuration
public class MyConfiguration{
        @Bean
         public MyTest myTest(){
                    return new MyTest();
          }
}
任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到spring的IoC容器,方法名将默认成为该bean的id。
bean与bean之间的依赖则直接调用该JavaConfig类中的bean创建方法就可以了。

其他重要的Annotation1、@ComponentScan
@ComponentScan告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。例如:
@Configuration  
@EnableWebMvc  
@ComponentScan(basePackages = { "com.apress.prospringmvc.bookstore.web" })  
public class WebMvcContextConfiguration extends WebMvcConfigurerAdapter {  
      ...

2、@PropertySource和@PropertySources
@PropertySource用于加载.properties文件内容,并将其中的属性加载到IoC容器中。例如:
@Configuration
@PropertySource(“classpath:application_1.properties”)
@PropertySource(“classpath:application_2.properties”)
public class MyConfiguration{
          ...
}

其他重要的Annotation

@PropertySources用于加载多个.properties文件内容,并将其中的属性加载到IoC容器中。例如:
@Configuration
@PropertySources({
       @PropertySource(“classpath:application_1.properties”),
       @PropertySource(“classpath:application_2.properties”)
})
public class MyConfiguration{
          ...
}

spring boot 初体验

spring boot 是spring框架对“约定优先于配置”理念的最近实践的产物

spring boot 启动类:
package com.crystal;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AojiWebApplication {
          public static void main(String[] args) {
              SpringApplication.run(AojiWebApplication.class, args);
          }
}

@SpringBootApplication的工作机制
@SpringBootApplication是一个“三体”结构,实际上是一个符合Annotation:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication{...}
最重要的三个Annotation为:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
此3个Annotation被称作三体结构。

@Configuration

实际上@Configuration被包含在@SpringBootConfiguration中。@Configuration在前面已经聊过,它就是JavaConfig形式的IoC容器配置类使用的@Configuration。一般在springboot的启动类直接标注@SpringBootConfiguration即可。

@EnableAutoConfiguration

利用spring框架里以@Enable开头的Annotation,并且借助@Import的支持,收集和注册特定场景相关的bean。

@ComponentScan

自动扫描并加载符合条件的组件或bean定义,最终将这些bean加载到容器中。实际上我们可以手工单个注册,不一定非要通过批量的自动扫描完成。

SpringBoot程序启动的一站式解决方案

SpringApplication将一个典型的Spring应用启动的流程“模块化”,在没有特殊需求的情况下,默认模块化的执行流程就可以满足需求了。
在有特殊需求的情况下,SpringApplication在合适的流程节点开放了一系列不同类型的扩展点,我们可以通过这些扩展点对SpringBoot程序的启动和关闭进行扩展。

SpringApplication的执行流程

SpringApplication的run方法的实现的主要流程归纳如下:
1、如果我们使用的是SpringApplication的静态run方法,那么这个方法首先创建一个SpringApplication的实例,然后在调用该实例的run方法。
       SpringApplication在实例初始化之前,会做如下几件事情:
       1、根据classpath里面是否存在某个特征类(org.springframework.web.context.ConfigurableWebApplicationContext)来决定是否创建一个为web应用使用的ApplicationContext类型,还是创建一个标准Standalone应用使用的ApplicationContext类型;
        2、使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationContextInitializer。
        3、使用SpringFactoriesLoader在应用的classpath中查找并加载所有可用的ApplicationListener。
2、SpringApplication实例初始化完成并完成设置后,就开始执行run方法的逻辑。首先通过SpringFactoriesLoader查找到并加载的SpringApplicationRunListener,调用它们的started()方法。
3、创建并配置当前Springboot应用将要使用的Environment。
4、遍历调用所有SpringApplicationRunListener的environmentPrepared()方法,通知它们Environment已准备好。

5、如果SpringApplication的showBanner属性被设置为true,则打印banner。

6、根据用户是否明确设置了ApplicationContextClass类型以及初始化阶段的推断结果,决定该为当前的SpringBoot应用创建什么类型的ApplicationContext并创建完成,并将之前设置好的Environment给ApplicationContext使用。

7、ApplicationContext创建好之后,ApplicationContext借助SpringFactoriesLoader,查找加载classpath中可用的ApplicationContextInitializer,然后遍历调用这些ApplicationContextInitializer的initialize(applicationContext)方法来对已经创建好的ApplicationContext进行进一步的处理。

8、遍历调用所有的SpringApplicationRunListener的contextPrepared()方法,通知它们:“SpringBoot应用使用的ApplicationContext准备好了”。

9、将之前通过@EnableAutoConfiguration获取的所有配置以及其他形式的IoC容器配置加载到已经准备完毕的ApplicationContext。

10、遍历调用所有的SpringApplicationRunListener的contextLoaded()方法,告知所有的SpringApplicationRunListener,ApplicationContext填装完毕。

11、调用ApplicationContext的refreash()方法,完成IoC容器可用的最后一到工序。

12、查找ApplicationContext是否注册了CommandLineRunner,如果有,则执行。

13、遍历调用所有的SpringApplicationRunListener的finished()方法。

SpringBoot启动精简示意图如下:


pringBoot项目简单实例:

利用springboot整合一套dubbo的消费者和生产者框架
从Dubbo官网直接拿来,看一下基于RPC层,服务提供方和服务消费方之间的调用关系,如图所示:


上图中,蓝色的表示与业务有交互,绿色的表示只对Dubbo内部交互。上述图所描述的调用流程如下:


1、服务提供方发布服务到服务注册中心;
2、服务消费方从服务注册中心订阅服务;
3、服务消费方调用已经注册的可用服务

依赖关系 消费者和生产者依赖同一个接口包提供的接口和数据模型


消费者依赖

<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>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<!--接口jar-->
<!--用户接口-->
<dependency><groupId>com.crystal</groupId><artifactId>user-api</artifactId><version>1.0-SNAPSHOT</version></dependency>
<!--商品接口-->
<dependency><groupId>com.crystal</groupId><artifactId>goods-api</artifactId><version>1.0-SNAPSHOT</version></dependency>
<!--接口jar end-->
<!-- Spring Boot Dubbo 依赖 -->
<dependency><groupId>io.dubbo.springboot</groupId><artifactId>spring-boot-starter-dubbo</artifactId><version>1.0.0</version></dependency>
<dependency><groupId>net.sourceforge.nekohtml</groupId><artifactId>nekohtml</artifactId><version>1.9.22</version></dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.32</version></dependency>
<dependency><groupId>net.sf.ehcache</groupId><artifactId>ehcache</artifactId><version>2.8.3</version></dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>4.3.2.RELEASE</version></dependency>
说明:1、与dubbo服务提供者共用的接口为:user-api,goods-api
             2、SpringBoot依赖spring-boot-starter-dubbo,在spring初始化时,将自动引用application.properties的配置,连接zookeeper获取dubbo服务信息

消费者application.properties配置

## Dubbo 服务消费者配置
spring.dubbo.application.name=consumer
spring.dubbo.registry.address=zookeeper://192.168.1.106:2181
dubbo.registry.check=false
spring.dubbo.scan=com.crystal.web.aoji.action.home
说明:
spring.dubbo.application.name:dubbo应用名
spring.dubbo.registry.address:注册服务器地址(zookeeper地址)
dubbo.registry.check:启动时检查依赖的服务是否可用
spring.dubbo.scan:服务引用包扫描,也就是指定哪些包将使用dubbo服务

消费者如何引用服务

@SuppressWarnings("all")
@Controller
@RequestMapping("/home/user")
public class UserAction extends ActionBase {
    private static Logger logger = Logger.getLogger(UserAction.class);
    @Value("${wechat.doLoginWx}")
    private String doLoginWx;
    @Autowired
    private BeanConfig beanConfig;
    @Autowired
    private BeanWeChat beanWeChat;
    @Autowired
    private BeanCacheManager beanCacheManager;
    @Reference(version = "1.0.0")
    private UserHandleInterface userHandleInterface;
    @Reference(version = "1.0.0")
    private GoodsHandleInterface goodsHandleInterface;
    ...
}
使用@Reference(version = "1.0.0")表名该服务为dubbo引用的服务,@Reference所在包为:com.alibaba.dubbo.config.annotation.Reference

生产者模块分布


一般我们可以将一个服务分为接口模块和服务模块,接口模块制定了服务提供者和服务消费者之间的接口调用格式和数据模型。使用maven打包程序,将接口模块上传到私有maven库,供不同的消费者使用。

生产者依赖

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>1.3.1</version></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<!--接口jar-->
<dependency><groupId>com.crystal</groupId><artifactId>goods-api</artifactId><version>1.0-SNAPSHOT</version></dependency>
<!--分页插件-->
<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>${pagehelper.version}</version></dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.32</version></dependency>
<!-- Spring Boot Dubbo 依赖 -->
<dependency><groupId>io.dubbo.springboot</groupId><artifactId>spring-boot-starter-dubbo</artifactId><version>${dubbo-spring-boot}</version></dependency>
<!-- druid阿里巴巴数据库连接池 -->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.26</version></dependency>
说明:1、与dubbo服务消费者共用的接口为:goods-api
             2、SpringBoot依赖spring-boot-starter-dubbo,在spring初始化时,将自动引用application.properties的配置,连接zookeeper发布和注册dubbo服务

生产者application.properties配置

## Dubbo 服务提供者配置
spring.dubbo.application.name=provider
spring.dubbo.registry.address=zookeeper://192.168.1.106:2181
spring.dubbo.protocol.name=dubbo
spring.dubbo.protocol.port=20882
dubbo.registry.check=false
spring.dubbo.scan=com.crystal.service.goods.impl
说明:
spring.dubbo.application.name:dubbo应用名
spring.dubbo.registry.address:注册服务器地址(zookeeper地址)
spring.dubbo.protocol.name:dubbo服务协议
spring.dubbo.protocol.port:dubbo服务开放端口
dubbo.registry.check:启动时检查依赖的服务是否可用
spring.dubbo.scan:服务发布扫描,也就是指定哪些包将发布和注册dubbo服务

生产者如何发布服务

@SuppressWarnings("all")
@Service(version = "1.0.0")
public class GoodsHandleInterfaceImpl implements GoodsHandleInterface {
    private static Logger logger = Logger.getLogger(GoodsHandleInterfaceImpl.class);
    @Autowired
    private MyCategoryMapper myCategoryMapper;
    ...
    @Override
    public List<MyCategory> getGoodsSubjects() {
         ...
    }
使用@Service(version = "1.0.0")注册和发布服务,该服务实现了接口GoodsHandleInterface,在消费者端,则直接使用GoodsHandleInterface 引用GoodsHandleInterfaceImpl 实例。
@Service所在包为:com.alibaba.dubbo.config.annotation.Service

使用spring boot有什么好处:
1、快速构建项目;
2、对主流开放框架的无配置集成;
3、项目可以独立运行,无须外部依赖Servlet容器;
4、极大地提高了开发、部署效率;
缺点:
请深入研究再做定夺。
谢谢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值