根据配置文件启动不同定时任务

问题:

一个项目中会包含多个定时任务(spring Scheduled),由于每个任务需要的资源等不同,需要将他们分开部署,但又不想分开项目编写,所以有了这个问题

【解决方法】:

(第三种是这里的解决方法)

1.注释掉不需要的定时任务的配置然后编译部署

问题:但这样线上部署的代码和master会有区别,分开的定时任务过多时每次都分开编译很麻烦

    //@Scheduled(cron = "${user.cancel.job.cron}")
    public void run(){
        System.out.println("UserCancelJob...");
    }
2.配置不需要的定时任务cron为多年后

问题:大致可以实现,但从代码配置上讲不完美,万一程序真跑到那一年(哈哈),从代码上来讲不是完美的方案。

    @Scheduled(cron = "${user.cancel.job.cron}")
    public void run(){...}
    配置文件
    user.cancel.job.cron=0 07 10 15 1 ? 2099
3.根据配置文件配置当前项目中不需要的配置,使spring不加载某些bean

不仅可用于当前这种定时任务,对于其他业务场景都可以,在项目启动时不加载某些bean,动态配置项目。


spring根据配置设置不加载的bean

实现过程

1.配置文件添加配置exclude.bean.classList

exclude.bean.classList=com.pack.a.class,com.pack.b.class

2.springboot启动类配置包扫描时配置不加载的bean过滤器

@ComponentScan(
        basePackages = "com.mjw",
        excludeFilters = {
                //根据注解过滤不加载的Bean
                //@ComponentScan.Filter(type=FilterType.ANNOTATION, value= {ExcludeBean.class}),
                //根据自定义过滤器过滤不加载的Bean
                @ComponentScan.Filter(type=FilterType.CUSTOM, value= {ExcludeBeanFilter.class})
        }
)

3.过滤器中根据配置文件判断是否包含配置
由于需要spring在加载bean前使用配置,不能使用spring注入方式加载配置文件,需要自己手动读取配置文件(工具类PropertiesUtils放在最后)

public class ExcludeBeanConfig {

    private static List<String> classList;
    
    static {
        classList = new ArrayList<>();
        Properties properties = null;
        try{
            properties = PropertiesUtils.loadProperties("classpath:application.properties");
        }catch (Exception e){
            throw new RuntimeException("APPLICATION CONF NOT EXIST...");
        }

        Object pro = properties.get(GlobalConstants.SPRING_EXCLUDE_BEAN_CONFIG);//就是exclude.bean.classList
        if(null != pro){
            classList = Arrays.asList(String.valueOf(pro).split(","));
        }
    }

    public static boolean contanisClass(String clazzName){
        if(StringUtils.isBlank(clazzName)){
            return false;
        }

        if(CollectionUtils.isEmpty(classList)){
            return false;
        }

        for(String clazz : classList){
            if(clazzName.equals(clazz)){
                return true;
            }
        }

        return false;
    }

}

不加载Bean过滤器

package cn.com.gc.core.spring;

import cn.com.gc.core.config.ExcludeBeanConfig;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

import java.io.IOException;

/**
 * @Description 不加载Bean过滤器
 * @Author MinJunWen
 * @Data 2019/7/4 11:01
 * @Version 1.0.0
 **/
public class ExcludeBeanFilter implements TypeFilter {

    /**
     * @Title
     * @Description 是否符合此过滤,返回true即符合。
     * @param
     * @return boolean
     * @throw
     * @author MinJunWen
     * @date 2019/7/4 11:02
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {

        if(ExcludeBeanConfig.contanisClass(metadataReader.getClassMetadata().getClassName())){
            return true;
        }

        return false;
    }

}

这样在项目启动后,会发现配置的bean就不会加载,相应的定时任务(或其他)都可以不执行了。


小结

此方法不仅可用于配置定时任务,其他相同需要根据配置动态加载或移除某些bean的场景都可以用到,spring配置不加载的bean过滤器时,除了自定义也提供了根据注解,根据正则,且面等多种方式。

这里留一下上面用到的工具类吧

public class PropertiesUtils {

	private static final String DEFAULT_ENCODING = "UTF-8";

	private static Log logger = LogFactory.getLog(PropertiesUtils.class);

	private static PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
	private static ResourceLoader resourceLoader = new DefaultResourceLoader();

	/**
	 * 载入多个properties文件, 相同的属性在最后载入的文件中的值将会覆盖之前的载入. 文件路径使用Spring Resource格式,
	 * 文件编码使用UTF-8.
	 * 
	 * @see org.springframework.beans.factory.config.PropertyPlaceholderConfigurer
	 */
	public static Properties loadProperties(String... resourcesPaths)
			throws IOException {
		Properties props = new Properties();

		for (String location : resourcesPaths) {

			logger.debug("Loading properties file from:" + location);

			InputStream is = null;
			try {
				Resource resource = resourceLoader.getResource(location);
				is = resource.getInputStream();
				propertiesPersister.load(props, new InputStreamReader(is,
						DEFAULT_ENCODING));
			} catch (IOException ex) {
				logger.info("Could not load properties from classpath:"
						+ location + ": " + ex.getMessage());
			} finally {
				if (is != null) {
					is.close();
				}
			}
		}
		return props;
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值