1. 程式人生 > >Spring高級話題(1)

Spring高級話題(1)

pack 編程 rgs frame ext.get 測試 framework ota cnblogs

所有代碼示例必須配置好Spring Spring項目的快速搭建.

1、Apring Aware

1.1、理論

Spring Aware的目的就是為了讓Bean獲得Spring容器的服務。
Spring 提供的Aware接口:

  • BeanNameAware:獲得容器中的Bean的名稱;
  • BeanFactoryAware:獲得當前bean factory,這樣容易調用容器服務;
  • ApplicationContextAware*:獲得當前application context,這樣容易調用容器服務;
  • MessageSourceAware: 獲得message source,這樣可以獲得文本信息;
  • ApplicationEventPublisher Aware:應用實踐發布器,可以發布事件;
  • ResourceLoaderAware: 獲得資源加載器,可以獲得外部資源文件;

1.2、示例

1)準備
新建一個text.tex,內容隨意,用於測試資源加載
技術分享圖片

2)演示Bean

package com.wisely.highlight_spring4.ch3.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{//實現接口,分別獲得Bean名稱和資源加載的服務
    
    private String beanName;
    private ResourceLoader loader;
    
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {//重寫ResourceLoaderAware的setResourceLoader方法
        this.loader = resourceLoader;
    }

    @Override
    public void setBeanName(String name) {//重寫BeanNameAware的setBeanName方法
        this.beanName = name;
    }
    
    public void outputResult(){
        System.out.println("Bean的名稱是:" + beanName);
        
        Resource resource = 
                loader.getResource("classpath:com/wisely/highlight_spring4/ch3/aware/test.txt");
        try{
            
            System.out.println("ResourceLoader加載的文件的內容為: " + IOUtils.toString(resource.getInputStream()));
            
           }catch(IOException e){
            e.printStackTrace();
           }
    
    }

}

3)配置類

package com.wisely.highlight_spring4.ch3.aware;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.wisely.highlight_spring4.ch2.aware")
public class AwareConfig {

}

4)測試

package com.wisely.highlight_spring4.ch3.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();
    }
}

技術分享圖片

2、多線程

2.1、理論

Spring通過任務執行器(TaskExecutor)來實現多線程和並發編程。使用TreadPoolTaskExecutor可以實現一個基於線程池的TaskExecutor。而實際開發中任務一般是非常阻礙的,即異步的,所以我們要在配置類中通過@EnableAsync開啟對異步任務的支持,並通過在實際執行的Bean方法中使用@Asynv註解來聲明其實一個異步任務。

2.2、示例

1)配置類

package com.wisely.highlight_spring4.ch3.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
@ComponentScan("com.wisely.highlight_spring4.ch3.taskexecutor")
@EnableAsync //開啟異步任務支持
public class TaskExecutorConfig implements AsyncConfigurer{//實現AsyncConfigurer接口

    @Override
    public Executor getAsyncExecutor() {//重寫getAsyncExecutor返回一個ThreadPoolTaskExecutor,這樣我們就獲得了一個基於線程池的TaskExecutor
         ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            taskExecutor.setCorePoolSize(5);
            taskExecutor.setMaxPoolSize(10);
            taskExecutor.setQueueCapacity(25);
            taskExecutor.initialize();
            return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }

}

2)業務執行類

package com.wisely.highlight_spring4.ch3.taskexecutor;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncTaskService {
    
    @Async //表明這個方法是個異步方法,如果註解在類級別,則表明該類所有的方法都是異步方法,而這裏的方法自動被註入使用ThreadPoolTaskExecutor作為TaskExecutor
    public void executeAsyncTask(Integer i){
        System.out.println("執行異步任務: "+i);
    }

    @Async
    public void executeAsyncTaskPlus(Integer i){
        System.out.println("執行異步任務+1: "+(i+1));
    }

}

4)測試

package com.wisely.highlight_spring4.ch3.taskexecutor;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    
    public static void main(String[] args) {
         AnnotationConfigApplicationContext context =
                    new AnnotationConfigApplicationContext(TaskExecutorConfig.class);
         
         AsyncTaskService asyncTaskService = context.getBean(AsyncTaskService.class);
         
         for(int i =0 ;i<5;i++){
             asyncTaskService.executeAsyncTask(i);
             asyncTaskService.executeAsyncTaskPlus(i);
            }
            context.close();
    }
}

技術分享圖片

Spring高級話題(1)