你好,游客 登录 注册 搜索
背景:
阅读新闻

使用Spring缓存数据

[日期:2017-01-10] 来源:  作者: [字体: ]

本指南将指导您完成在Spring所托管bean上启用缓存的过程。

What you’ll build

您将构建一个应用程序,在一个简单的book repository中启用缓存。

What you’ll need

How to complete this guide

与大多数[Spring 入门指南]一样( https://spring.io/guides),您可以从头开始并完成每个步骤,也可以绕过已经熟悉的基本设置步骤。 无论如何,你最终得到工作代码。

当你做完这一切, 你可以根据 gs-caching/complete 中的代码检查结果.

Build with Gradle

首先你设置一个基本的构建脚本。 你可以使用任何你喜欢的一个来构建项目,当使用Spring构建应用程序时,但是需要使用 Gradle 和 Maven 来写你的代码。 如果你不熟悉任何一个,请参考 使用Gradle构建Java项目 或 使用Maven构建Java项目 。

Create the directory structure

在您选择的项目目录中,创建以下子目录结构; 例如,在 nix 系统上使用`mkdir -p src / main / java / hello’:

└── src
    └── main
        └── java
            └── hello

Create a Gradle build file

下面是 initial Gradle build file .

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.3.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'

jar {
    baseName = 'gs-caching'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-cache")
}

Spring Boot gradle插件 提供了许多方便的功能:

  • 它收集类路径上的所有jar,并构建一个单独的,可运行的“über-jar”,这使得执行和传递服务更加方便。
  • 它搜索 public static void main() 方法来标记为可运行类。
  • 它提供了一个内置的依赖解析器,设置版本号匹配 Spring Boot dependencies . 你可以覆盖任何你想要的版本,但它会默认为Boot的选择的版本集。

Build with Maven

首先你设置一个基本的构建脚本。 你可以使用任何你喜欢的一个来构建项目,当使用Spring构建应用程序,但是需要使用 Maven 来构建你的代码。 如果你不熟悉Maven,请参考 使用Maven构建Java项目 .

Create the directory structure

在您选择的项目目录中,创建以下子目录结构; 例如,在 nix 系统上使用`mkdir -p src / main / java / hello’:

└── src
    └── main
        └── java
            └── hello

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-caching</artifactId>
    <version>0.1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.3.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Spring Boot Maven插件 提供了许多方便的功能:

  • 它收集类路径上的所有jar,并构建一个单独的,可运行的“über-jar”,这使得执行和运输服务更加方便。
  • 它搜索 public static void main() 方法来标记为可运行类。
  • 它提供了一个内置的依赖解析器,设置版本号匹配 Spring Boot dependencies . 你可以覆盖任何你想要的版本,但它会默认为Boot的选择的版本集。

Build with your IDE

Create a book repository

首先,让我们为你的book创建一个非常简单的模型

src/main/java/hello/Book.java

package hello;

public classBook{

    private String isbn;
    private String title;

    publicBook(String isbn, String title){
        this.isbn = isbn;
        this.title = title;
    }

    publicStringgetIsbn(){
        return isbn;
    }

    publicvoidsetIsbn(String isbn){
        this.isbn = isbn;
    }

    publicStringgetTitle(){
        return title;
    }

    publicvoidsetTitle(String title){
        this.title = title;
    }

    @Override
    publicStringtoString(){
        return "Book{" + "isbn='" + isbn + '\'' + ", title='" + title + '\'' + '}';
    }

}

和该model的存储库:

src/main/java/hello/BookRepository.java

package hello;

public interfaceBookRepository{

    BookgetByIsbn(String isbn);

}

您可以使用 Spring Data 在很多的SQL或NoSQL stores中提供repository仓库的实现,但是出于本指南的目的, 将使用模拟一些延迟(网络服务,慢延迟等)进行简单地的实现。

src/main/java/hello/SimpleBookRepository.java

package hello;

import org.springframework.stereotype.Component;

@Component
public classSimpleBookRepositoryimplementsBookRepository{

    @Override
    publicBookgetByIsbn(String isbn){
        simulateSlowService();
        return new Book(isbn, "Some book");
    }

    // Don't do this at home
    privatevoidsimulateSlowService(){
        try {
            long time = 3000L;
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }

}

simulateSlowService 是故意在每个 getByIsbn 调用中插入一个三秒延迟。 这是一个例子,稍后,你可以通过加入缓存来看到加速的效果。

Using the repository

接下来,连接repository库并使用它访问一些书。

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public classApplication{

    publicstaticvoidmain(String[] args){
        SpringApplication.run(Application.class, args);
    }

}

@ SpringBootApplication是一个方便的注解,添加了以下所有内容:

  • @ Configuration将类标记为应用程序上下文的bean定义的来源。
  • @ EnableAutoConfiguration告诉Spring Boot根据类路径设置,其他bean和各种属性设置开始添加bean。
  • 通常你会为Spring MVC应用程序添加@ EnableWebMvc,但是Spring Boot在类路径上看到 spring-webmvc 时会自动添加它。这将应用程序标记为Web应用程序,并激活关键行为,如设置一个“DispatcherServlet”。
  • @ ComponentScan告诉Spring在hello包中寻找其他组件,配置和服务,允许它找到控制器。

main()方法使用Spring Boot的SpringApplication.run()方法来启动应用程序。你有注意到一行XML?没有 web.xml 文件。这个Web应用程序是100%纯Java,你不必处理配置任何管道或基础设施。

还有一个 CommandLineRunner ,注入 BookRepository 和 用不同的参数调用它几次。

src/main/java/hello/AppRunner.java

package hello;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public classAppRunnerimplementsCommandLineRunner{

    private static final Logger logger = LoggerFactory.getLogger(AppRunner.class);

    private final BookRepository bookRepository;

    publicAppRunner(BookRepository bookRepository){
        this.bookRepository = bookRepository;
    }

    @Override
    publicvoidrun(String... args)throwsException{
        logger.info(".... Fetching books");
        logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
        logger.info("isbn-4567 -->" + bookRepository.getByIsbn("isbn-4567"));
        logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
        logger.info("isbn-4567 -->" + bookRepository.getByIsbn("isbn-4567"));
        logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
        logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
    }

}

如果你尝试在此时运行应用程序,您会注意到它很慢,即使您几次检索完全相同的书。

2014-06-05 12:15:35.783  ... : .... Fetching books
2014-06-05 12:15:40.783  ... : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2014-06-05 12:15:43.784  ... : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2014-06-05 12:15:46.786  ... : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}

从时间戳可以看出,每本书花了大约三秒钟来检索,即使它是相同的标题被重复抓取。

Enable caching

让我们在你的SimpleBookRepository上启用缓存,这样书就会被缓存在 books 缓存中。

src/main/java/hello/SimpleBookRepository.java

package hello;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public classSimpleBookRepositoryimplementsBookRepository{

    @Override
    @Cacheable("books")
    publicBookgetByIsbn(String isbn){
        simulateSlowService();
        return new Book(isbn, "Some book");
    }

    // Don't do this at home
    privatevoidsimulateSlowService(){
        try {
            long time = 3000L;
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }

}

您现在需要启用缓存注解的处理

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching
public classApplication{

    publicstaticvoidmain(String[] args){
        SpringApplication.run(Application.class, args);
    }

}

@EnableCaching 注解触发检查并处理每个Spring bean用于存在对公共方法的缓存注解。如果找到这样的注解,则自动创建代理以拦截方法调用并相应地处理缓存行为。

缓存处理的相应注解是 Cacheable , CachePut 和 CacheEvict .有关更多详细信息,可以参考javadocs和 文档 。

Spring Boot会自动配置一个合适的 CacheManager ,作为相关缓存。有关更多详细信息,请参阅 Spring Boot文档 。

我们的示例不使用特定的缓存库,因此我们的缓存存储是使用 ConcurrentHashMap的简单回退。缓存抽象支持各种各样的缓存库,并完全符合JSR-107(JCache)。

Build an executable JAR

您可以使用Gradle或Maven从命令行运行应用程序。 或者,您可以构建单个可执行文件,其中包含所有必需的依赖关系,类和资源,并运行它。 这使得在整个开发生命周期中,易于跨不同环境将服务作为应用程序进行发布,维护版本和部署等等。

如果您使用Gradle,可以使用 ./gradlew bootRun 运行应用程序。 或者你可以使用./gradlew build 来构建JAR文件。 然后可以运行JAR文件:

java -jar build/libs/gs-caching-0.1.0.jar

如果您使用Maven,可以使用 ./mvnw spring-boot:run 运行应用程序。 或者你可以用 ./mvnw clean package 构建JAR文件。 然后可以运行JAR文件:

java -jar target/gs-caching-0.1.0.jar
**上面的过程将创建一个可运行的JAR。 您也可以选择 build a classic WAR file

Test the application

现在缓存已启用,您可以再次执行它,并通过添加或不使用相同的isbn的额外调用查看差异。 你应该可以看到其产生明显的区别。

2016-09-01 11:12:47.033  .. : .... Fetching books
2016-09-01 11:12:50.039  .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2016-09-01 11:12:53.044  .. : isbn-4567 -->Book{isbn='isbn-4567', title='Some book'}
2016-09-01 11:12:53.045  .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2016-09-01 11:12:53.045  .. : isbn-4567 -->Book{isbn='isbn-4567', title='Some book'}
2016-09-01 11:12:53.045  .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2016-09-01 11:12:53.045  .. : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}

This excerpt from the console shows that the first time to fetch each title took three seconds, but each subsequent call was near instantaneous.

从控制台的这段日志显示,第一次获取每个标题花了三秒钟,但每个后续的访问接近瞬间。

最后

恭喜! 你刚刚通过Springcache在托管bean上启用了缓存。

收藏 推荐 打印 | 录入:admin | 阅读:
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款