《Spring Guides系列学习》guide6 - guide10

要想全面快速学习Spring的内容,最好的方法肯定是先去Spring官网去查阅文档,在Spring官网中找到了适合新手了解的官网Guides,一共68篇,打算全部过一遍,能尽量全面的了解Spring框架的每个特性和功能。
在这里插入图片描述
接着上篇看过的guide5,接着往下看。

guide6、Accessing data with neo4j

讲述了使用neo4j,将应用程序数据存储在基于图形的数据库neo4j中并从中检索数据。
首先了解下neo4j是什么

在这里插入图片描述
然后下载和启动neo4j

brew install neo4j

neo4j start

启动完成后,开始准备程序。
1、先定义一个简单的POJO

@Node
public class Person {

  @Id @GeneratedValue private Long id;

  private String name;

  private Person() {
    // Empty constructor required as of Neo4j API 2.0.5
  };

  public Person(String name) {
    this.name = name;
  }

  /**
   * Neo4j doesn't REALLY have bi-directional relationships. It just means when querying
   * to ignore the direction of the relationship.
   * https://dzone.com/articles/modelling-data-neo4j
   */
  @Relationship(type = "TEAMMATE")
  public Set<Person> teammates;

  public void worksWith(Person person) {
    if (teammates == null) {
      teammates = new HashSet<>();
    }
    teammates.add(person);
  }

  public String toString() {

    return this.name + "'s teammates => "
      + Optional.ofNullable(this.teammates).orElse(
          Collections.emptySet()).stream()
            .map(Person::getName)
            .collect(Collectors.toList());
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

Guide涉及注解:

@Node注解用来注释Person类。当 Neo4j 存储它时,会创建一个新节点。这个类也有一个id标记。@Node注解,声明这是一个节点类。

@Id与@GeneratedValue注解,声明该成员是一个自动生成的id,Neo4j中的id为长整型类Long;

@Relationship注解,声明该成员是与本节点有关的关系的列表,

type参数为该关系的名称; direction参数为该关系的方向,离开本节点(OUTGOING,默认)或进入本节点(INCOMING)。
注意:当关系一端的节点声明了此关系,另一端的节点一定不能声明同一关系,否侧会由于循环嵌套出现stackOverflow错误!

2、创建查询接口类

public interface PersonRepository extends Neo4jRepository<Person, Long> {

  Person findByName(String name);
  List<Person> findByTeammatesName(String name);
}

PersonRepository接口类继承了Neo4jRepository接口,并入参运行的类型Person. 该接口带有许多操作,包括标准的 CRUD(创建、读取、更新和删除)操作。

在本例中,添加了findByName,它通过name来寻找匹配的person节点。

3、具体的增删改操作

@Bean
CommandLineRunner demo(PersonRepository personRepository) {
   return args -> {

      personRepository.deleteAll();

      Person greg = new Person("Greg");
      Person roy = new Person("Roy");
      Person craig = new Person("Craig");

      List<Person> team = Arrays.asList(greg, roy, craig);

      log.info("Before linking up with Neo4j...");

      team.stream().forEach(person -> log.info("\t" + person.toString()));

      personRepository.save(greg);
      personRepository.save(roy);
      personRepository.save(craig);

      greg = personRepository.findByName(greg.getName());
      greg.worksWith(roy);
      greg.worksWith(craig);
      personRepository.save(greg);

      roy = personRepository.findByName(roy.getName());
      roy.worksWith(craig);
      personRepository.save(roy);

      log.info("Lookup each person by name...");
      team.stream().forEach(person -> log.info(
            "\t" + personRepository.findByName(person.getName()).toString()));

      List<Person> teammates = personRepository.findByTeammatesName(greg.getName());
      log.info("The following have Greg as a teammate...");
      teammates.stream().forEach(person -> log.info("\t" + person.getName()));
   };
}

运行程序后,结果显示:

Before linking up with Neo4j...
	Greg's teammates => []
	Roy's teammates => []
	Craig's teammates => []

Lookup each person by name...
	Greg's teammates => [Roy, Craig]
	Roy's teammates => [Greg, Craig]
	Craig's teammates => [Roy, Greg]

guide7、buildinhg a restful web service with spring boot actuator

讲的是使用actuator创建一个restful服务。

Spring Boot Actuator是Spring Boot提供用于对应用系统进行自省和监控的功能模块,基于此开发人员可以方便地对应用系统某些监控指标进行查看、统计、审计、指标收集等。Actuator提供了基于Http端点或JMX来管理和监视应用程序。

它与SpringWeb提供的@Controller的对外服务有什么区别呢?它们都可以通过Http的方式让外部来访问应用程序,但功能的定义边界不同。就像上面说的Actuator通常用于应用程序本身运行情况的监控和操作,而@Controller更多的是业务层面运用。

通过Actuator可以监控应用程序的Health健康信息、Info应用信息、HTTP
Request跟踪信息、Metrics信息、@RequestMapping的路径信息、应用程序的各种配置信息、程序请求的次数时间等各种信息。

集成actuator到Spring boot项目,只需要添加依赖pom即可. 然后启动项目后,就可以通用http的方式访问其提供的端口。

$ curl localhost:9001/actuator/health
{"status":"UP"}

guide8、Integrating Data

主要讲的是使用Spring Integration创建一个应用服务,该应用程序从RSS提要(Spring Blog)检索数据,操作数据,然后将其写入文件。并且使用传统的Spring Integration XML配置。

定义一个Spring Integration流

  • 在Spring.io上阅读RSS提要中的博客文章。
  • 将它们转换为一个易于阅读的字符串,由文章标题和文章的URL组成。
  • 将该字符串追加到文件的末尾(/tmp/si/SpringBlog)。

实施起来步骤也简单,就是引入jar包,然后编写integration.xml配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int="http://www.springframework.org/schema/integration"
    xmlns:file="http://www.springframework.org/schema/integration/file"
    xmlns:feed="http://www.springframework.org/schema/integration/feed"
    xsi:schemaLocation="http://www.springframework.org/schema/integration/feed https://www.springframework.org/schema/integration/feed/spring-integration-feed.xsd
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/integration/file https://www.springframework.org/schema/integration/file/spring-integration-file.xsd
        http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd">

    <feed:inbound-channel-adapter id="news" url="https://spring.io/blog.atom" auto-startup="${auto.startup:true}">
        <int:poller fixed-rate="5000"/>
    </feed:inbound-channel-adapter>

    <int:transformer
            input-channel="news"
            expression="payload.title + ' @ ' + payload.link + '#{systemProperties['line.separator']}'"
            output-channel="file"/>

    <file:outbound-channel-adapter id="file"
            mode="APPEND"
            charset="UTF-8"
            directory="/tmp/si"
            filename-generator-expression="'${feed.file.name:SpringBlog}'"/>

</beans>

这里有三个整合元素:

feed:inbound-channel-adapter:检索文章的入站适配器,每个轮询一个。按照这里的配置,它每5秒轮询一次。帖子被放置在一个名为news的频道中(对应于适配器的ID)。

int:transformer:转换新闻频道中的条目(com.rometools.rome.feed.synd.SyndEntry),提取条目的标题(payload.title)和链接(payload.link),并将它们连接到可读的String中(并添加换行符)。然后将字符串发送到名为file的输出通道。

<file:outbound-channel-adapter>:将内容从其通道(命名为文件)写入文件的出站通道适配器。具体来说,就像这里配置的那样,它将文件通道中的任何内容追加到/tmp/si/SpringBlog的文件中。

Guide涉及注解:

@ImportResource
用于导入 Spring 的配置文件,例如:spring-mvc.xml、application-Context.xml。

Spring Boot 里面没有Spring 配置文件,都是通过 Java 代码进行配置。如果我们自己编写了配置文件,Spring Boot 是不能自动识别,此时需要使用 @ImportResource 注解将自己的配置文件加载进来。


guide9、Creating a Batch Service

构建一个服务,从CSV电子表格导入数据,使用自定义代码转换数据,并将最终结果存储在数据库中。

涉及到了spring batch, 将以下bean添加到BatchConfiguration类中,以定义读取器、处理器和写入器:

@Bean
public FlatFileItemReader<Person> reader() {
  return new FlatFileItemReaderBuilder<Person>()
    .name("personItemReader")
    .resource(new ClassPathResource("sample-data.csv"))
    .delimited()
    .names(new String[]{"firstName", "lastName"})
    .fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
      setTargetType(Person.class);
    }})
    .build();
}

@Bean
public PersonItemProcessor processor() {
  return new PersonItemProcessor();
}

@Bean
public JdbcBatchItemWriter<Person> writer(DataSource dataSource) {
  return new JdbcBatchItemWriterBuilder<Person>()
    .itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
    .sql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)")
    .dataSource(dataSource)
    .build();
}

reader()创建一个ItemReader。它查找一个名为sample-data.csv的文件,并使用足够的信息解析每个行项以将其转换为Person。

processor()创建之前定义的PersonItemProcessor的实例,用于将数据转换为大写。

writer(DataSource)创建一个ItemWriter。它的目标是JDBC目的地,并自动获得@EnableBatchProcessing创建的dataSource的副本。它包括插入单个Person所需的SQL语句,由Java bean属性驱动。

@Bean
public Job importUserJob(JobRepository jobRepository,
    JobCompletionNotificationListener listener, Step step1) {
  return new JobBuilder("importUserJob", jobRepository)
    .incrementer(new RunIdIncrementer())
    .listener(listener)
    .flow(step1)
    .end()
    .build();
}

@Bean
public Step step1(JobRepository jobRepository,
    PlatformTransactionManager transactionManager, JdbcBatchItemWriter<Person> writer) {
  return new StepBuilder("step1", jobRepository)
    .<Person, Person> chunk(10, transactionManager)
    .reader(reader())
    .processor(processor())
    .writer(writer)
    .build();
}

第一个方法定义作业,第二个方法定义单个步骤。作业是按步骤构建的,其中每个步骤都涉及读取器、处理器和写入器。

在这个作业定义中,需要一个增量器,因为作业使用数据库来维护执行状态。然后列出每个步骤(尽管这个作业只有一个步骤)。作业结束,Java API生成一个配置完美的作业。

在步骤定义中,定义一次写入多少数据。在本例中,它一次最多写入10条记录。接下来,使用前面注入的bean配置读取器、处理器和写入器。

批处理配置的最后一点是在作业完成时获得通知的方法,如下:

@Component
public class JobCompletionNotificationListener implements JobExecutionListener {

  private static final Logger log = LoggerFactory.getLogger(JobCompletionNotificationListener.class);

  private final JdbcTemplate jdbcTemplate;

  @Autowired
  public JobCompletionNotificationListener(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
  }

  @Override
  public void afterJob(JobExecution jobExecution) {
    if(jobExecution.getStatus() == BatchStatus.COMPLETED) {
      log.info("!!! JOB FINISHED! Time to verify the results");

      jdbcTemplate.query("SELECT first_name, last_name FROM people",
        (rs, row) -> new Person(
          rs.getString(1),
          rs.getString(2))
      ).forEach(person -> log.info("Found <{{}}> in the database.", person));
    }
  }
}

主要就是介绍了Spring batch,一个轻量级批处理框架的简单应用。https://juejin.cn/post/7064591679189155854

在这里插入图片描述


guide10、Building a Hypermedia-Driven RESTful Web Service

主要讲的是使用Spring HATEOAS构建一个超媒体驱动的restful 服务。

Spring HATEOAS: 一个api库,可以使用它创建指向Spring MVC控制器的链接,构建资源表示,并控制如何将它们呈现为受支持的超媒体格式。

感觉背后思想就是响应中包含指向其它资源的链接。客户端可以利用这些链接和服务器交互。

非HATEOAS的响应例子:

GET /posts/1 HTTP/1.1
Connection: keep-alive
Host: blog.example.com
{
    "id" : 1,
    "body" : "My first blog post",
    "postdate" : "2015-05-30T21:41:12.650Z"}

HATEOAS的响应例子:

{
    "id" : 1,
    "body" : "My first blog post",
    "postdate" : "2015-05-30T21:41:12.650Z",
    "links" : [
        {
            "rel" : "self",
            "href" : http://blog.example.com/posts/1,
            "method" : "GET"
        }
    ] 
}

上面的例子中,每一个在links中的link都包含了三部分:

rel:描述href指向的资源和现有资源的关系
href:用户可以用来检索资源或者改变应用状态的URI
method:和此URI需要的http方法

比较复杂:https://www.cnblogs.com/kaixinyufeng/p/8283289.html

涉及到rest成熟度模型,第四层次就是HATEOAS,在资源表达中包含了链接信息,客户端可根据链接来发现可执行的动作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值