Spring基础(二)高级话题

Spring Aware

Spring 的依赖注入的最大亮点就是你所以的Bean对Spring 容器的存在是没有意识的。
但是在实际项目中,经常 要用到Spring 容器本身的功能资源,这时你的Bean必须要意识到Spring 容器的存在,才能调用Spring 所提供的资源,这就是所谓的Spring Aware。其实Spring Aware本来就是Spring 设计用来框架内部使用的。
这里写图片描述
AwareService.java

@Service
//实现BeanNameAware,ResourceLoaderAware,获得Bean名称和资源加载的服务。
public class AwareService implements BeanNameAware,ResourceLoaderAware{
    private String beanName;
    private ResourceLoader loader;

    //实现ResourceLoaderAware,需重写setResourceLoader。
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.loader = resourceLoader;       
    }

    //实现BeanNameAware,需重写setBeanName。
    @Override
    public void setBeanName(String name) {
        this.beanName = name;       
    }

    public void outputResult() throws IOException {
        System.out.println("Bean的名称为:"+beanName);
        Resource resource = loader.getResource("classpath:test/test.txt");
        System.out.println("ResourceLoader加载的文件内容为:"+IOUtils.toString(resource.getInputStream()));
        System.out.println(loader);

    }

}

AwareConfig.java

@Configuration
@ComponentScan("ch3")
public class AwareConfig {
}

TestSpringAware.java

public class TestSpringAware{

    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AwareConfig.class);
        AwareService awareService = context.getBean(AwareService.class);
        awareService.outputResult();
        context.close();    
    }
}

这里写图片描述

多线程

Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程。使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor。
TaskExecutorConfig.java

@Configuration
@ComponentScan("ch3")
@EnableAsync   //开启异步任务支持
public class TaskExecutorConfig implements AsyncConfigurer{
    //实现AsyncConfigurer接口并重写getAsyncExecutor方法,并返回一个ThreadPoolTaskExecutor,
    //这样我们就获得了一个基于线程池TaskExecutor。
    @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;
    }

}

AsyncTaskService.java

@Service
public class AsyncTaskService {
@Async   //@Async注解声明该方法为异步方法。
public void executeAsyncTask(Integer i)
{
    System.out.println("执行异步任务:"+i);
}
@Async  //如果注解在类级别,则表明该类所有的方法都是异步方法。
public void executeAsyncTaskPlus(Integer i)
{
    System.out.println("执行异步任务+1:"+(i+1));
}
}

TestAsyn.java

public class TestAsyn{

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

这里写图片描述

计划任务

计划任务在Spring中实现变得异常的简单。
ScheduledTaskService.java

@Service
public class ScheduledTaskService {
private static final SimpleDateFormat dataformat = new SimpleDateFormat("HH:mm:ss");
@Scheduled(fixedRate = 5000) //通过@Scheduled声明该方法是计划任务,使用fixedRate属性每隔固定时间执行。
public void reportCurrentTime()
{
    System.out.println("每隔五秒执行一次"+dataformat.format(new Date()));
}
@Scheduled(cron = "0 45 19 ? * *")//cron属性在指定时间执行,本例为每天19点45分执行;cron是UNIX和类UNIX系统下的定时任务。
public void fixTimeExecution()
{
    System.out.println("在指定时间"+dataformat.format(new Date())+"执行");
}
}

TaskSchedulerConfig.java

@Configuration
@ComponentScan("ch3")
@EnableScheduling //开启对计划任务的支持
public class TaskSchedulerConfig {

}

TestTaskScheduler.java

public class TestTaskScheduler{

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TaskSchedulerConfig.class);
    }
}

这里写图片描述

条件注解

@Configuration根据满足某一特定条件创建一个特定的Bean。
WindowsCondition.java

public class WindowsCondition implements Condition{

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().getProperty("os.name").contains("Windows");
    }

}

LinuxCondition.java

public class LinuxCondition implements Condition{
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return context.getEnvironment().getProperty("os.name").contains("Linux");
    }
}

ListService.java

public interface ListService {
public String showListCmd();
}

Windows.java

public class Windows implements ListService{

    @Override
    public String showListCmd() {
        return "dir";
    }
}

Linux.java

public class Linux implements ListService{

    @Override
    public String showListCmd() {   
        return "ls";
    }   
}

ConditionConfig.java

@Configuration
public class ConditionConfig {
@Bean
@Conditional(WindowsCondition.class)//通过@Conditional,符合Windows条件则实例化Windows。
public Windows windows()
{
    return new Windows();
}

@Bean
@Conditional(LinuxCondition.class)//通过@Conditional,符合Linux条件则实例化Linux。
public Linux linux()
{
    return new Linux();
}
}

TestConditional.java

public class TestConditional{

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
        ListService listService = context.getBean(ListService.class);
        System.out.println(context.getEnvironment().getProperty("os.name")+"系统下的列表命令为:"
                +listService.showListCmd());
        context.close();
    }
}

这里写图片描述

组合注解与元注解

元注解其实就是可以注解到别的注解上的注解,被注解的注解称之为组合注解,组合注解具备注解其上的元注解的功能。
MyConfiguration.java

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration  //组合@Configuration元注解
@ComponentScan  //组合@ComponentScan元注解
public @interface MyConfiguration {
   String [] value() default {};  //覆盖value参数
}

现在@MyConfiguration就是一个组合注解。具备@Configuration与@ComponentScan的功能。
DemoConfig.java

@MyConfiguration("ch3")
public class DemoConfig {

}

DemoService.java

@Service
public class DemoService {
public void outputResult() {
    System.out.println("从组合注解配置照样获得的bean");
}
}

TestCombinationOfannotation.java

public class TestCombinationOfannotation{

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
        DemoService demoService = context.getBean(DemoService.class);
        demoService.outputResult();
        context.close();
    }
}

这里写图片描述

参考书籍:Spring Boot 实战
以上只是学习所做的笔记, 以供日后参考。如有错误请指正,谢谢啦!!!

猜你喜欢

转载自blog.csdn.net/z1790424577/article/details/81036602
今日推荐