一、关于注解
Component
:组件,所有的Java Bean都可以认为是一个组件,交托给Spring管理,需要使用的地方使用autowired
注入。Service
:一般作为业务实现注解,表示业务实现层。Repository
:表示dao层,并且将数据库相关异常进行了转化和封装,封装为Spring的数据访问异常类型。Controller
:通常用于控制层,用于处理web端相关请求等。Autowired
:自动注入,即在容器中查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring会将其注入到@Autowired
标注的变量中。
二、定时任务
使用注解实现定时任务步骤如下:
1、写一个定时任务的类,该类采用@Component
注解修饰,该类中包含一个定时任务,使用@Scheduled
注解修饰,表示该方法是一个定时任务。
package com.lanxuewei.utils.schedule;
import com.lanxuewei.utils.schedule.service.AutoTaskTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
/**
* @author lanxuewei Create in 2018/10/31 10:31
* Description: 定时任务测试
*/
@Component
public class AutoTaskScheduleTest {
@Scheduled(fixedDelay = 3000)
public void test() {
System.out.println("我是一个定时任务");
}
}
说明:该定时任务就是一个简单的打印字符串功能,fixedDelay=3000表示该定时任务等待上次任务时间完成以后3s后执行。
2、在启动类中添加上@EnableScheduling
注解,表示开启定时任务。
package com.lanxuewei.utils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableScheduling
public class UtilsApplication {
public static void main(String[] args) {
SpringApplication.run(UtilsApplication.class, args);
}
}
3、其实完成以上1、2步骤就可以了,但是这种情况下如果你有多个定时任务,Spring会创建一个容量为1的线程池,也许你希望有一个大一点的池子来管理定时任务的线程,这时候可以加一个线程池配置类,如下:
package com.lanxuewei.utils.schedule.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/**
* @author lanxuewei Create in 2018/10/31 10:39
* Description: 配置线程池的大小
*/
@Configuration
@EnableScheduling
public class UtilApplicationSchedulingConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setScheduler(taskExecutor());
}
@Bean()
public Executor taskExecutor() {
// 设置线程池大小
return Executors.newScheduledThreadPool(5);
}
}
4、fixedDelay和fixedRate意思不一样,且执行效果也不一样,fixedDelay表示下次任务会在当前任务完成开始计时,到时间后开始;fixedRate表示下次任务在这次任务开始后开始计时,到时间以后开始执行。
注意:
由于fixedDelay表示该次定时任务完成以后下次任务才会开启,该定时任务可能会引起的坑就是,当前任务阻塞无响应或者死循环的时候,该定时任务就会一直处于假死状态,下一次任务认为上一次任务一直未完成,所以不会开启。
5、按时间段或者一定时间后再开始执行,SpringBoot的定时任务支持cron表达式,例子如下:
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点清理一次
说明
:可能很多读者表示这种表达式不好理解或是不熟练,这里解释就暂时不说明了,直接给出一个可直接生成表达式的网站,需要的读者可以自己直接界面操作自动生成表达式,地址为:自动生成cron表达式
。
三、Spring上下文
由于Spring托管了所有Bean,但如果操作的本类并没有交给Spring托管,不可直接注入需要的Bean,但希望获取指定Bean,可以采用获取Spring上下文手动获取方式。
获取Spring上下文:
package com.lanxuewei.utils.spring.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* @author lanxuewei Create in 2019/4/15 19:27
* Description: 设置以及获取Spring上下文
*/
@Component
@Lazy(false)
public class ApplicationContextRegister implements ApplicationContextAware {
private static ApplicationContext APPLICATION_CONTEXT;
/**
* 设置Spring上下文
* @param applicationContext Spring上下文
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
APPLICATION_CONTEXT = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return APPLICATION_CONTEXT;
}
}
使用:
package com.lanxuewei.utils.spring.config;
import com.lanxuewei.utils.data.converter.model.People;
import org.junit.jupiter.api.Test;
/**
* @author lanxuewei Create in 2019/4/15 19:33
* Description: 使用Spring山下文直接获取Bean
*/
public class ApplicationContextRegisterTest {
@Test
public void test() {
Object object = ApplicationContextRegister.getApplicationContext().getBean("people");
People people = (People) object;
System.out.println(people);
}
}