「Spring Boot実戦」学習(二):Springの常用配置
記事の目次 springの基本構成 Scope Spring ELとリソース呼び出し Benの初期化と廃棄 Profile Apple Event Springの高級話題 Spring Aware マルチスレッド 計画タスク 条件注 コンボ注釈とメタ注釈 テスト スプリングの基本構成
Scrope
Scopeでは、Spring容器がビーンをどのように作成するかの例を述べている.SpringのScropeには以下のような種類があります. Singletonは、一つのSpring容器の中で一つのBeanだけのインスタンスであり、これはデフォルトの構成である.単例です Prottypeは、毎回ビーンを作成する例 を呼び出します. Requestは、Webプロジェクトにおいて、http requestごとにビーンの例を新たに作成する. Sessionは、Webプロジェクトにおいて、http sessionごとにビーンの新しいインスタンスを作成する. Global Sessionは、potalアプリケーションで、global http sessionごとにビーンの新しい例を作成します. 使用例
spring開発では、一般ファイル、URL、プロファイル、システム環境変数などを含め、Springの表現言語を使ってリソースの注入を行うことができます.
サンプルコードは以下の通りです.
pom.xml添加
SpringはBeanの初期化と廃棄時にいくつかの操作ができます.次の2つの方法を提供します. Java構成の方式:@BeanのinitMethodとdestroyMethodを使用する(xml構成のinit-methodとdestroy-methodに相当する) 注釈の方式:JSR-250@PostCostructと@Predestry を利用します.
例:
Profileは、異なる環境で異なる構成を使用するためにサポートされています.は、EvironmentのActive Profilesを設定することにより、現在のcontextが使用する必要がある配置環境を設定する.開発において@Profile注解類または方法を使用して、異なる場合に実用化の異なるビーンを選択することができる. は、jvmのspring.profiles.activeパラメータを設定することにより設定環境を設定する. Webプロジェクトは、Servletのcontext parameterに設定されている. アプリイベントイベント
Springのイベントは流れに従う必要があります.カスタムイベント、Application Event を継承します.カスタムイベントモニター、Appplication Listener を実現します.容器を使ってイベントを発表します. コードの例
カスタムイベント:
Spring Aware
awareは感知という意味で、SpringはAware関連のインターフェースを提供して使用する目的はビーンにいくつかの容器が持つ資源と機能を呼び出せるようにすることです.本の中では大体この意味です.
私が理解しているのは、容器そのものの機能インターフェースを暴露して、容器に基づいていくつかの機能を広げてくれます.これに対応すると,ビームと容器の結合性が増強される.
例のコードは次の通りです.BeanNameAwareを実現するとbean name属性が得られます.Resource Loader Awareを実現すると、コンテナのリソースキャリアが得られます.
Springは、タスクアクチュエータTaskExectorにより、マルチスレッドと同時プログラムを実現します.ThreadPoolTaskExectorを使用して、スレッド池に基づくTaskExectorを実現することができます.実際の開発において、任務は一般的に非阻害的であり、すなわち非同期的である.構成クラスでは、@EnbleAsyncを通じて非同期タスクのサポートを開始し、実際に実行されるBeanの方法で@Aync注釈を使用して、これは非同期タスクであると宣言します.
クラスの設定
設定クラスの注釈@EnbleSchedulingで計画タスクに対するサポートを開始し、タスクを実行する方法で@Scheduledを注釈することによって、これは計画的なタスクであると宣言します.
クラスを設定:
springは@Conditionalを通じて、ある特定の条件を満たすことによって特定のBeanを作成することができます.
以下のコード例は、Coditionインターフェースを実現することにより、matches方法を実現して判断条件を構成する.
元注とは別の注を付けることができます.注釈された注釈を組み合わせ注と呼びます.
コンビネーションコメントは、その構成のメタ注釈の機能を有する.
例として、注釈を定義します.
テスト用の依存性を追加します.
@RunWith(SpringJUnit 4 Class)はSpring Testcontext Fraameweorkの機能を提供しています.ContectConfigration(clases={TestConfig.class}プロファイルを設定します.Active Profilesが活動のプロファイルを決めに行きます.
Scrope
Scopeでは、Spring容器がビーンをどのように作成するかの例を述べている.SpringのScropeには以下のような種類があります.
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope("prototype")
public class DemoPrototypeService {
}
Spring ELとリソースコールspring開発では、一般ファイル、URL、プロファイル、システム環境変数などを含め、Springの表現言語を使ってリソースの注入を行うことができます.
サンプルコードは以下の通りです.
pom.xml添加
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.3version>
dependency>
@Service
public class DemoService {
@Value(" ")
private String another;
public String getAnother() {
return another;
}
public void setAnother(String another) {
this.another = another;
}
}
@Configuration
@ComponentScan("com.xhf.sample4")
//
@PropertySource("classpath:com/xhf/sample4/test.properties")
public class ElConfig {
//
@Value("I love you")
private String normal;
//
@Value("#{systemProperties['os.name']}")
private String osName;
//
@Value("#{T(java.lang.Math).random()*100.0}")
private double randomNumber;
// bean 。demoService bean
@Value("#{demoService.another}")
private String fromAnother;
//
@Value("classpath:com/xhf/sample4/test.txt")
private Resource testFile;
//
@Value("http://www.baidu.com")
private Resource testUrl;
//
@Value("${book.name}")
private String bookName;
//Environment
@Autowired
private Environment environment;
// Bean
@Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigure() {
return new PropertySourcesPlaceholderConfigurer();
}
public void outputResource() {
System.out.println(normal);
System.out.println(osName);
System.out.println(randomNumber);
System.out.println(fromAnother);
try {
System.out.println(IOUtils.toString(testFile.getInputStream()));
System.out.println(IOUtils.toString(testUrl.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(bookName);
System.out.println(environment.getProperty("book.name"));
}
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(ElConfig.class);
ElConfig resourceService = context.getBean(ElConfig.class);
resourceService.outputResource();
context.close();
}
}
:
I love you
Linux
37.23290117950025
hello world
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8>......
spring boot
spring boot
Beanの初期化と廃棄SpringはBeanの初期化と廃棄時にいくつかの操作ができます.次の2つの方法を提供します.
例:
public class BeanWayService {
public void init() {
System.out.println("@Bean-init-method");
}
public BeanWayService() {
super();
System.out.println(" -BeanWayService");
}
public void destroy() {
System.out.println("@Bean-destroy-method");
}
}
@Component
public class JSR250WayService {
@PostConstruct
public void init() {
System.out.println("JSR250-init-method");
}
public JSR250WayService() {
super();
System.out.println(" -JSR250WayService");
}
@PreDestroy
public void destroy() {
System.out.println("JSR250-destroy-method");
}
}
@Configuration
@ComponentScan("com.xhf.sample5")
public class PrePostConfig {
@Bean(initMethod="init", destroyMethod="destroy") //
BeanWayService beanWayService() {
return new BeanWayService();
}
}
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(PrePostConfig.class);
BeanWayService beanWayService = context.getBean(BeanWayService.class);
JSR250WayService jsr250WayService = context.getBean(JSR250WayService.class);
context.close();
}
}
ProfileProfileは、異なる環境で異なる構成を使用するためにサポートされています.
Springのイベントは流れに従う必要があります.
カスタムイベント:
public class DemoEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
private String msg;
public DemoEvent(Object source, String msg) {
super(source);
this.setMsg(msg);
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
事件の傍受@Component
public class DemoListener implements ApplicationListener<DemoEvent>{
@Override
public void onApplicationEvent(DemoEvent event) {
String msg = event.getMsg();
System.out.println(" bean-demopublisher :"+msg);
}
}
イベントリリース@Component
public class DemoPublisher {
@Autowired
ApplicationContext context;
public void publish(String msg) {
context.publishEvent(new DemoEvent(this, msg));
}
}
設定ファイル@Configuration
@ComponentScan("com.xhf.sample6")
public class EventConfig {
}
実行プロセスpublic class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(EventConfig.class);
DemoPublisher publisher = context.getBean(DemoPublisher.class);
publisher.publish("hello world");
context.close();
}
}
Springの高級話題Spring Aware
awareは感知という意味で、SpringはAware関連のインターフェースを提供して使用する目的はビーンにいくつかの容器が持つ資源と機能を呼び出せるようにすることです.本の中では大体この意味です.
私が理解しているのは、容器そのものの機能インターフェースを暴露して、容器に基づいていくつかの機能を広げてくれます.これに対応すると,ビームと容器の結合性が増強される.
例のコードは次の通りです.BeanNameAwareを実現するとbean name属性が得られます.Resource Loader Awareを実現すると、コンテナのリソースキャリアが得られます.
package com.xhf.aware;
import java.io.IOException;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
@Service
public class AwareService implements BeanNameAware, ResourceLoaderAware {
private ResourceLoader resourceLoader;
private String name;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public void setBeanName(String name) {
this.name = name;
}
public void outputResult() {
System.out.println("Bean :" + name);
Resource resource = resourceLoader.getResource("classpath:com/xhf/aware/test.txt");
try {
String content = IOUtils.toString(resource.getInputStream());
System.out.println(content);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
クラスの設定package com.xhf.aware;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.xhf.aware")
public class AwareConfig {
}
実行コードpackage com.xhf.aware;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AwareConfig.class);
AwareService awareService = context.getBean(AwareService.class);
awareService.outputResult();
context.close();
}
}
結果は以下の通りですBean :awareService
hello world!!!!!!!!!!!!
マルチスレッドSpringは、タスクアクチュエータTaskExectorにより、マルチスレッドと同時プログラムを実現します.ThreadPoolTaskExectorを使用して、スレッド池に基づくTaskExectorを実現することができます.実際の開発において、任務は一般的に非阻害的であり、すなわち非同期的である.構成クラスでは、@EnbleAsyncを通じて非同期タスクのサポートを開始し、実際に実行されるBeanの方法で@Aync注釈を使用して、これは非同期タスクであると宣言します.
クラスの設定
package com.xhf.taskexecutor;
import java.util.concurrent.Executor;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
@EnableAsync
@ComponentScan("com.xhf.taskexecutor")
public class TaskExecutorConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return null;
}
}
非同期タスクの定義:package com.xhf.taskexecutor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncTaskService {
@Async
public void executeAsyncTask(Integer i) {
System.out.println(" :" + i);
}
@Async
public void executeAsyncTaskPlus(Integer i) {
System.out.println(" +1:" + (i+1));
}
}
クラスを起動し、非同期のタスクを実行します.package com.xhf.taskexecutor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsyncTaskService taskService = context.getBean(AsyncTaskService.class);
for (int i = 0; i < 10; i++) {
taskService.executeAsyncTask(i);
taskService.executeAsyncTaskPlus(i);
}
context.close();
}
}
計画的任務設定クラスの注釈@EnbleSchedulingで計画タスクに対するサポートを開始し、タスクを実行する方法で@Scheduledを注釈することによって、これは計画的なタスクであると宣言します.
クラスを設定:
package com.xhf.schedule;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@ComponentScan("com.xhf.schedule")
@EnableScheduling
public class TaskSchedulerConfig {
}
計画タスクを定義:package com.xhf.schedule;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class ScheduledTaskService {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate=5000)
public void reportCurrentTime() {
System.out.println(" 5 ,currentTime: "+dateFormat.format(new Date()));
}
@Scheduled(cron="0 28 11 ? * *")
public void fixTimeExecution() {
System.out.println(" ,currentTime: "+dateFormat.format(new Date()));
}
}
スタートクラス、計画タスクを実行します.package com.xhf.schedule;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskSchedulerConfig.class);
}
}
条件の説明springは@Conditionalを通じて、ある特定の条件を満たすことによって特定のBeanを作成することができます.
以下のコード例は、Coditionインターフェースを実現することにより、matches方法を実現して判断条件を構成する.
package com.xhf.conditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Windows");
}
}
package com.xhf.conditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Linux");
}
}
一つのインターフェースを定義し、その後に異なる条件に従って異なるオブジェクトを実装します.package com.xhf.conditional;
public interface ListService {
public String showListCmd();
}
package com.xhf.conditional;
public class WindowsListService implements ListService {
@Override
public String showListCmd() {
return "dir";
}
}
package com.xhf.conditional;
public class LinuxListService implements ListService{
@Override
public String showListCmd() {
return "ls";
}
}
設定ファイルは@Condational条件を使って異なるBeanを実装します.package com.xhf.conditional;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConditionConfig {
@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService() {
return new WindowsListService();
}
@Bean
@Conditional(LinuxCondition.class)
public ListService linuxListService() {
return new LinuxListService();
}
}
クラスを開始package com.xhf.conditional;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
ListService listService = context.getBean(ListService.class);
System.out.println(listService.showListCmd());
context.close();
}
}
組み合わせ注解と元注元注とは別の注を付けることができます.注釈された注釈を組み合わせ注と呼びます.
コンビネーションコメントは、その構成のメタ注釈の機能を有する.
例として、注釈を定義します.
package com.xhf.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@ComponentScan
public @interface MyConfiguration {
String[] value() default{};
}
ビーンを定義しますpackage com.xhf.annotation;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
public void outPut() {
System.out.println(" Bean ");
}
}
クラスの設定package com.xhf.annotation;
@MyConfiguration("com.xhf.annotation")
public class DemoConfig {
}
クラスを開始package com.xhf.annotation;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
DemoService demoService = context.getBean(DemoService.class);
demoService.outPut();
context.close();
}
}
テストテスト用の依存性を追加します.
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>4.1.6.RELEASEversion>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
dependency>
ビーンを定義しますpackage com.xhf.test;
public class TestBean {
private String context;
public TestBean(String context) {
super();
this.context = context;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
}
プロファイルの実装によって構成クラスが異なります.package com.xhf.test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
public class TestConfig {
@Bean
@Profile("dev")
public TestBean devTestBean() {
return new TestBean(" form dev profile ");
}
@Bean
@Profile("prod")
public TestBean prodTestBean() {
return new TestBean(" form prod profile ");
}
}
テストケース、@RunWith(SpringJUnit 4 Class)はSpring Testcontext Fraameweorkの機能を提供しています.ContectConfigration(clases={TestConfig.class}プロファイルを設定します.Active Profilesが活動のプロファイルを決めに行きます.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.xhf.test.TestBean;
import com.xhf.test.TestConfig;
import junit.framework.Assert;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestConfig.class})
@ActiveProfiles("prod")
public class DemoBeanIntegrationTests {
@Autowired
private TestBean testBean;
@Test
public void prodBean() {
String expect = " form prod profile ";
String actual = testBean.getContext();
Assert.assertEquals(expect, actual);
}
}