Aware:意識到,目的是讓Bean得到到Spring容器的服務,能夠直接繼承ApplicationContextAware得到Spring容器的全部服務,但原則上是使用到什麼接口,就實現什麼接口。java
將txt文件裏面的內容,讀取到控制檯。linux
1234567890qwertyuiop!@#$%^&*()去沃爾特與IOP平
複製代碼
package com.eleven.aware1;
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 // 表示將當前類注入到Spring容器中,成爲Spring管理的一個Bean
// BeanNameAware:得到到容器中Bean的名稱
// ResourceLoaderAware:獲取外部資源文件
public class AwareService implements BeanNameAware, ResourceLoaderAware {
private String beanName;
private ResourceLoader loader;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
// TODO Auto-generated method stub
this.loader = resourceLoader;
}
@Override
public void setBeanName(String name) {
// TODO Auto-generated method stub
this.beanName = name;
}
public void outputResult() {
// 獲取到文件的名稱
System.out.println("Bean的名稱:" + beanName);
// 加載外部資源文件
Resource resource = loader.getResource("classpath:com/eleven/aware1/test.txt");
// 輸出資源文件的內容
try {
System.out.println("輸出資源文件的內容:" + IOUtils.toString(resource.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
複製代碼
package com.eleven.aware1;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration // 聲明當前類是一個配置類
@ComponentScan("com.eleven.aware1") // 自動掃描包下面的因此配置
public class AwareConfig {
}
複製代碼
package com.eleven.aware1;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
// 將AnnotationConfigApplicationContext注入到Spring容器裏面,成爲Spring管理的一個Bean
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AwareConfig.class);
// 得到AwareService聲明的Bean
AwareService awareService = context.getBean(AwareService.class);
awareService.outputResult();
context.close();
}
}
複製代碼
Bean的名稱:awareService
輸出資源文件的內容:1234567890qwertyuiop!@#$%^&*()去沃爾特與IOP平
複製代碼
Spring是經過任務執行器(TaskExecutor)來實現多線程和併發編程。使用ThreadPoolTaskExecutor能夠實現一個基於線程的TaskExecutor。spring
實現一個多線程。apache
package com.eleven.thread1;
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 // 聲明當前類是一個配置類
@ComponentScan("com.eleven.thread1") // 自動掃描包下面的全部配置
@EnableAsync // 開啓異步任務支持
public class TaskExecutorConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
// TODO Auto-generated method stub
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); // 線程池
taskExecutor.setCorePoolSize(5); // 核心池大小
taskExecutor.setMaxPoolSize(10); // 最大池大小
taskExecutor.setQueueCapacity(25); // 排隊容量
taskExecutor.initialize(); // 初始化
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
// TODO Auto-generated method stub
return null;
}
}
複製代碼
package com.eleven.thread1;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service // 聲明當前類是Spring管理的一個Bean
public class AsynTaskService {
@Async // 表示該方法是異步方法
public void executeAsyncTask(Integer i) {
System.out.println("執行異步任務" + i);
}
@Async
public void executeAsyncTaskPlus(Integer i) {
System.out.println("執行異步任務+1++++++++++" + (i + 1));
}
}
複製代碼
package com.eleven.thread1;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
AsynTaskService asynTaskService = context.getBean(AsynTaskService.class);
for (int i = 0; i < 10; i++) {
asynTaskService.executeAsyncTask(i);
asynTaskService.executeAsyncTaskPlus(i);
}
context.close();
}
}
複製代碼
執行異步任務+1++++++++++1
執行異步任務+1++++++++++3
執行異步任務2
執行異步任務+1++++++++++4
執行異步任務4
執行異步任務+1++++++++++5
執行異步任務5
執行異步任務+1++++++++++6
執行異步任務+1++++++++++2
執行異步任務6
執行異步任務0
執行異步任務1
執行異步任務3
執行異步任務8
執行異步任務+1++++++++++8
執行異步任務+1++++++++++10
執行異步任務7
執行異步任務+1++++++++++7
執行異步任務9
執行異步任務+1++++++++++9
複製代碼
在配置類上加入@EnableScheduling註解,開啓對計劃任務的支持,而後在要執行計劃任務的方法上加入@Scheduled註解,聲明是一個計劃任務。編程
利用Spring的計劃任務,每隔5秒執行一次。windows
package com.eleven.planttask1;
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 dataFormat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000) // 開啓計劃任務,默認單位是毫秒
public void reportCurrentTime() {
System.out.println("每隔5秒執行一次:" + dataFormat.format(new Date()));
}
@Scheduled(cron = "0 28 11 ? * *") // 設置的是天天的11點28分開始執行
public void fixTimeExecution() {
System.out.println("在指定的時間:" + dataFormat.format(new Date() + "執行"));
}
}
複製代碼
package com.eleven.planttask1;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration // 聲明當前類是一個配置類
@ComponentScan("com.eleven.planttask1")
@EnableScheduling // 開啓對計劃任務的支持
public class TaskSchedulerConfig {
}
複製代碼
package com.eleven.planttask1;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskSchedulerConfig.class);
}
}
複製代碼
每隔5秒執行一次:19:54:06
每隔5秒執行一次:19:54:11
每隔5秒執行一次:19:54:16
每隔5秒執行一次:19:54:21
每隔5秒執行一次:19:54:26
複製代碼
根據特定條件建立特定的Bean。多線程
根據特定條件來控制Bean的建立行爲。併發
模擬程序在不一樣的操做系統中,若在Windows系統下運行程序,則輸出命令dir;若在Linux系統下運行,則輸出列表命令ls。異步
package com.eleven.conditional1;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class WindowsConditional implements Condition {
/** * ConditionContext:條件 * getEnvironment:獲取環境 * getProperty:獲取屬性 * contains:包含 */
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Windows");
}
}
複製代碼
package com.eleven.conditional1;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LinuxConditional implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return context.getEnvironment().getProperty("os.name").contains("Linux");
}
}
複製代碼
package com.eleven.conditional1;
public interface ListService {
public String showListCmd();
}
複製代碼
package com.eleven.conditional1;
import org.springframework.stereotype.Service;
@Service
public class WindowsListService implements ListService{
@Override
public String showListCmd() {
return "dir";
}
}
複製代碼
package com.eleven.conditional1;
import org.springframework.stereotype.Service;
@Service
public class LinuxListService implements ListService{
@Override
public String showListCmd() {
return "ls";
}
}
複製代碼
package com.eleven.conditional1;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration // 聲明當前類是一個配置類
public class ConditionConfig {
@Bean
@Conditional(WindowsConditional.class)
public ListService windowsListService() {
return new WindowsListService();
}
@Bean
@Conditional(LinuxConditional.class)
public ListService linuxListService() {
return new LinuxListService();
}
}
複製代碼
7.運行ide
package com.eleven.conditional1;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
WindowsListService windowsListService = context.getBean(WindowsListService.class);
System.out.println(
context.getEnvironment().getProperty("os.name") + "系統下的命令列表爲:" + windowsListService.showListCmd());
/* * LinuxListService linuxListService = context.getBean(LinuxListService.class); * System.out.println( context.getEnvironment().getProperty("os.name") + * "系統下的命令列表爲:" + linuxListService.showListCmd()); */
}
}
複製代碼
8.輸出
Windows 10系統下的命令列表爲:dir
複製代碼
元註解:能夠注入到別的註解上的註解。
組合註解:被註解的註解叫作組合註解。
模擬一個元註解和組合註解
package com.eleven.annotation1;
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 WiselyConfiguration {
String[] value() default{};
}
複製代碼
package com.eleven.annotation1;
import org.springframework.stereotype.Service;
@Service
public class DemoService {
public void outputResult() {
System.out.println("從組合配置同樣能夠得到Bean");
}
}
複製代碼
package com.eleven.annotation1;
@WiselyConfiguration("com.eleven.annotation1")
public class DemoConfig {
}
複製代碼
package com.eleven.annotation1;
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.outputResult();
context.close();
}
}
複製代碼
從組合配置同樣能夠得到Bean
複製代碼
單元測試:只針對當前的類和方法進行測試。
集成測試:將系統的各個部分組合在一塊兒進行測試。
將系統的各個部分組合在一塊兒進行集成測試。
<!-- Spring Test 支持 -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
複製代碼
package com.eleven.test1;
public class TestBean {
private String content;
public TestBean(String content) {
super();
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
複製代碼
package com.eleven.test1;
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("開發環境");
}
@Bean
@Profile("prod")
public TestBean prodTestBean() {
return new TestBean("生產環境");
}
}
複製代碼
package com.eleven.test1;
import org.junit.Assert;
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;
@RunWith(SpringJUnit4ClassRunner.class) // 在JUint環境下面
@ContextConfiguration(classes = { TestConfig.class }) // 加載配置文件TestConfig
@ActiveProfiles("prod") // 聲明當前的環境
public class DemoTest {
@Autowired
private TestBean testBean;
@Test
public void prodTest() {
String expected = "生產環境";
String actual = testBean.getContent();
Assert.assertEquals(expected, actual);
}
}
複製代碼
運行測試,爲綠色表示經過,紅色表示未經過。
複製代碼