SpringBoot系列(2)---无配置文件配置基础2
2017-07-06 15:29
926 查看
上一篇文章的传送门:SpringBoot系列(1)---无配置文件配置基础1
一、Spring Aware
其实我在写Spring的博客已经用过了SpringAware ,当时使用的是BeanFactoryAware。其实Aware主要为我们提供获得Spring容器信息和服务的接口,让我们可以在bean中获得很多Spring 提供的服务。当然其实直接使用ApplicatonContext已经获得非常多的服务了。
BeanNameAware 获得容器中Bean的名称
BeanFactoryAware 获得当前bean factory,使用factory调用容器服务。
ApplicationContextAware 获得当前的application context。
MessageSourceAware 获得message source 获得文本信息
ApplicationEventPublisherAware 应用事件发布器,同样我们可以使用applicationContext 进行事件发布
ResourceLoaderAware 获得资源加载器,用于读取外部资源文件
其中 setBean 和 setResourceLoader 是BeanNameAware 和 ResourceLoaderAware的接口方法。这样我们就可以通过这些方法去获得beanName 和 resourceLoader了。
其实如果我们不去实现ResourceLoaderAware 还可以通过IOC的方式获得ResourceLoader
二、Spring多线程
Spring通过任务执行器TaskExecutor实现多线程和并发编程。使用ThreadPoolTaskExecutor可以实现一个基于线程池的TaskExecutor。
我们需要在配置类加上@EnableAsync 启动异步功能,并创建一个taskExecutor方法,返回一个ThreadPoolTaskExecutor,这样就获得了一个基于线程池的TaskExecutor
当然我们没有必要使用 executor.execute(new Runnable() {... 去创建一个任务,将这个任务交给Spring。我们只需要在我们的Bean中对需要异步的方法和类打上@Async就完事了。聪明的你已经猜到了,如果在类中打上@Async就代表整个类所有方法都异步,如果在方法上打@Async就代表这个方法是异步。
Main方法:
main finish !
executeAsyncTask sum : 499500
Process finished with exit code 0
从输出我们可以看出我们的main方法是没有被阻塞的。
二、@Profile 的升级版 @Conditional
上一篇博客我写了Profile的使用,conditional可以说profile的升级版。conditional可以根据条件获得不同的bean,例如操作系统、日期等等。我们需要实现一个实现condition接口的类。里面会一个matches方法,根据不同的需要放回是否满足条件。
我们可以根据不同的操作系统获得不同的bean
然后我定义了一个Bean主要去读取文件内容
配置类如下:
如果是windows 系统我会读取C盘下的text.txt文件,如果是mac会读取桌面的text.txt文件,然后看看我们的Main方法:
三、组合注解
可以看到我们的配置类,一大堆配置就不能少写一点配置吗?或者一次性打一个注解就把所有需要的东西都启动上。嗯~可以
我们会将以上这些annotation配置写到一个annotation当中:
最后在我们的配置类当中打上我们写的MyConfig即可
四、Spring Test
在开始之前我们在maven添加SpringTest的依赖支持:
然后我们就可以在Junit当中通过依赖注入获得相关的bean并进行测试:
@RunWith 没什么好说的,就是要Junit 有SpringTest的支持。
@ActiveProfiles 是需要测试的profile环境
@ContextConfiguration 是配置类
然后直接测试跑就可以了,但是需要注意的是Spring 需要Junit4.12以上的版本的。
一、Spring Aware
其实我在写Spring的博客已经用过了SpringAware ,当时使用的是BeanFactoryAware。其实Aware主要为我们提供获得Spring容器信息和服务的接口,让我们可以在bean中获得很多Spring 提供的服务。当然其实直接使用ApplicatonContext已经获得非常多的服务了。
BeanNameAware 获得容器中Bean的名称
BeanFactoryAware 获得当前bean factory,使用factory调用容器服务。
ApplicationContextAware 获得当前的application context。
MessageSourceAware 获得message source 获得文本信息
ApplicationEventPublisherAware 应用事件发布器,同样我们可以使用applicationContext 进行事件发布
ResourceLoaderAware 获得资源加载器,用于读取外部资源文件
@Service public class AwareService implements BeanNameAware,ResourceLoaderAware{ private String beanName; private ResourceLoader resourceLoader; public void setBeanName(String s) { this.beanName = s; } public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } public void test() throws IOException { System.out.println("Bean name is : " + beanName); Resource resource = this.resourceLoader.getResource("classpath:text.txt"); System.out.println("text.txt -> " + IOUtils.toString(resource.getInputStream())); } }
其中 setBean 和 setResourceLoader 是BeanNameAware 和 ResourceLoaderAware的接口方法。这样我们就可以通过这些方法去获得beanName 和 resourceLoader了。
其实如果我们不去实现ResourceLoaderAware 还可以通过IOC的方式获得ResourceLoader
@Service public class AwareService implements BeanNameAware{ private String beanName; @Autowired private ResourceLoader resourceLoader; public void setBeanName(String s) { this.beanName = s; } public void test() throws IOException { System.out.println("Bean name is : " + beanName); Resource resource = this.resourceLoader.getResource("classpath:text.txt"); System.out.println("text.txt -> " + IOUtils.toString(resource.getInputStream())); } }
二、Spring多线程
Spring通过任务执行器TaskExecutor实现多线程和并发编程。使用ThreadPoolTaskExecutor可以实现一个基于线程池的TaskExecutor。
我们需要在配置类加上@EnableAsync 启动异步功能,并创建一个taskExecutor方法,返回一个ThreadPoolTaskExecutor,这样就获得了一个基于线程池的TaskExecutor
@Configuration @ComponentScan("com.tony") @EnableAspectJAutoProxy @EnableAsync public class ApplicationConfig { public Executor taskExecutor(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); executor.initialize(); return executor; } }
当然我们没有必要使用 executor.execute(new Runnable() {... 去创建一个任务,将这个任务交给Spring。我们只需要在我们的Bean中对需要异步的方法和类打上@Async就完事了。聪明的你已经猜到了,如果在类中打上@Async就代表整个类所有方法都异步,如果在方法上打@Async就代表这个方法是异步。
@Service public class AsyncTaskService { @Async public void executeAsyncTask() throws InterruptedException { int sum = 0; for(int i=0;i<1000;i++){ Thread.sleep(10); sum+= i; } System.out.println("executeAsyncTask sum : " + sum); } }
Main方法:
public class App { public static void main( String[] args ) throws IOException, InterruptedException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class); AsyncTaskService service = context.getBean(AsyncTaskService.class); service.executeAsyncTask(); System.out.println("main finish !"); } }
main finish !
executeAsyncTask sum : 499500
Process finished with exit code 0
从输出我们可以看出我们的main方法是没有被阻塞的。
二、@Profile 的升级版 @Conditional
上一篇博客我写了Profile的使用,conditional可以说profile的升级版。conditional可以根据条件获得不同的bean,例如操作系统、日期等等。我们需要实现一个实现condition接口的类。里面会一个matches方法,根据不同的需要放回是否满足条件。
public class WindowsCondition implements Condition { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { return conditionContext.getEnvironment().getProperty("os.name").toLowerCase().contains("windows"); } }
public class MacCondition implements Condition { public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { return conditionContext.getEnvironment().getProperty("os.name").toLowerCase().contains("mac"); } }
我们可以根据不同的操作系统获得不同的bean
然后我定义了一个Bean主要去读取文件内容
@Component public class TextLoader { @Autowired private ResourceLoader resourceLoader; private String path; public TextLoader(String path) { this.path = path; } public String fileLoad() throws IOException { Resource resource = resourceLoader.getResource(this.path); return IOUtils.toString(resource.getInputStream()); } }
配置类如下:
@Configuration @ComponentScan("com.tony") @EnableAspectJAutoProxy @EnableAsync public class ApplicationConfig { @Bean("textLoader") @Conditional(WindowsCondition.class) public TextLoader getWinTextLoader(){ return new TextLoader("file://C:\\text.txt"); } @Bean("textLoader") @Conditional(MacCondition.class) public TextLoader getMacTextLoader(){ return new TextLoader("file:///Users/yanzhichao/Desktop/text.txt"); } }
如果是windows 系统我会读取C盘下的text.txt文件,如果是mac会读取桌面的text.txt文件,然后看看我们的Main方法:
public static void main( String[] args ) throws IOException, InterruptedException { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class); TextLoader loader = context.getBean(TextLoader.class); System.out.println(loader.fileLoad()); }
三、组合注解
可以看到我们的配置类,一大堆配置就不能少写一点配置吗?或者一次性打一个注解就把所有需要的东西都启动上。嗯~可以
@Configuration @ComponentScan("com.tony") @EnableAspectJAutoProxy @EnableAsync public class ApplicationConfig {
我们会将以上这些annotation配置写到一个annotation当中:
@Configuration @ComponentScan() @EnableAspectJAutoProxy @EnableAsync public @interface MyConfig { //覆盖value参数 String[] value() default{}; }
最后在我们的配置类当中打上我们写的MyConfig即可
@MyConfig("com.tony") public class ApplicationConfig {
四、Spring Test
在开始之前我们在maven添加SpringTest的依赖支持:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency>
然后我们就可以在Junit当中通过依赖注入获得相关的bean并进行测试:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = ApplicationConfig.class) @ActiveProfiles("dev") public class AppTest { @Autowired private TextLoader textLoader; @Test public void testTextLoader() throws IOException { String textContent = textLoader.fileLoad(); System.out.println("textContent : " +textContent); Assert.assertEquals("SDFGHJKL\n",textContent); } }
@RunWith 没什么好说的,就是要Junit 有SpringTest的支持。
@ActiveProfiles 是需要测试的profile环境
@ContextConfiguration 是配置类
然后直接测试跑就可以了,但是需要注意的是Spring 需要Junit4.12以上的版本的。
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
相关文章推荐
- SpringBoot系列(1)---无配置文件配置基础1
- Spring Boot干货系列:(二)配置文件解析
- Spring基础——在Spring Config 文件中配置 Bean(看了一半,看整个系列)
- Spring-Boot之基础 POM 文件和自动配置(maven)
- SpringBoot系列(3)---无配置文件SpringMVC
- Spring Boot教程(二)--- 推荐的基础 POM 文件和自动配置
- Spring Boot基础教程——配置文件-多环境配置
- (转)SpringBoot系列—基础配置
- Spring Boot干货系列:(二)配置文件解析
- 13-SpringBoot——Spring MVC基础-高级配置-文件上传
- SpringBoot 基础知识学习(二)——配置文件多环境配置
- Spring Boot系列 - 4. 读取配置文件(application.yml)中的属性值
- Spring Boot基础4-配置文件-多环境配置
- Spring Boot系列教程五:使用properties配置文件实现多环境配置
- Spring boot系列:配置文件(二)
- Spring Boot系列教程五:使用properties配置文件实现多环境配置
- 使用Gradle构建SpringBoot工程系列:第四篇:项目初始化(编辑build.gradle文件,引入项目基本配置及依赖)
- Spring Boot系列教程四:配置文件详解properties
- Spring Boot系列(二):Spring Boot的配置文件
- Spring Boot 系列(2) 配置文件的加载