Springboot实战第七天:(1)spring的计划任务ScheduledTask应用-2019-8-23

本文介绍了如何在Springboot中使用ScheduledTask,并探讨了@Enable注解的原理,包括@EnableScheduling、@EnableAspectJAutoProxy等,通过源码分析揭示了这些注解如何导入配置类并实现功能。
摘要由CSDN通过智能技术生成

紧接着昨天的来研究。

在之前的几次分析中大家可能会发现都会有配置一个配置类来启动注解,这个配置类会有@Configuration和
@ComponentScan("com.amarsoft.springboot.taskscheduler")这几个注解,其实这类注解是元注解,接下来实战下怎么将众多元注解组合为组合注解。这几天的项目都是在最开始的创建项目的方式步骤下创建完成后在项目中新建一个包去实践这个功能。

废话不多说直接上代码:

1,实例组合注解

package com.amarsoft.springboot.compositeannotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ComponentScan
@Configuration
public @interface WiselyConfiguration {
	String[] value() default{};
}

 

2,新的配置类

package com.amarsoft.springboot.compositeannotations;

@WiselyConfiguration("com.amarsoft.springboot.compositeannotations")
public class NewConfig {

}

使用@WiselyConfiguration代替@ComponentScan和@Configuration

3,演示服务bean

package com.amarsoft.springboot.compositeannotations;

import org.springframework.stereotype.Service;

@Service
public class CompositeAnnotationsService {
	public 	void outputResult(){
		System.out.println("从组合注解配置中获取同样的bean");
	}
}

4,

package com.amarsoft.springboot.compositeannotations;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class CompositeAnnotationApplication {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext  context=
				new AnnotationConfigApplicationContext(NewConfig.class);
		CompositeAnnotationsService cas=context.getBean(CompositeAnnotationsService.class);
		cas.outputResult();
		context.close();
	}
}

运行结果:

这个是元注解组合为组合注解的实战,当然还有一类注解,其实昨天的计划任务有用到的注解@EnableScheduling,这个主要是开启的是对计划任务的支持。下面就盘点下那些@Enable*的注解的简单工作的原理。

@EnableAspectJAutoProxy           开启对AspectJ的自动代理的支持

@EnableAsync                开启异步方法的支持

@EnableScheduling       开启对计划任务的支持

@EnableWebMvc            开启Web Mvc的配置支持

@EnableConfigurationProperties      开启对@ConfigurationProperties注解配置bean的支持

@EnableJpaRepositories     开启对Spring  Data JPA  Repository的支持

@EnableTransactionManagement      开启注解式事务的支持

@EnableCaching                  开启注解式缓存支持。

这种@Enable*的注解他底层的原理是怎么样子的呢,继续往下看:

通过简单的@Enable一来开启一项功能的支持,从而避免自己配置大量的代码,大大降低使用难度。那么这个神奇的功能的实现原理是什么呢?我们一起来研究一下。通过观察这些@Enable*注解的源码,我们发现所有的注解都有一个@Import注解,@lmport是用来导入配置类的,这也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean.这些导入的配置方式主要分为以下三种类型。

第一类直接导入配置类   以支持计划任务的@EnableScheduling注解为例

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}

 直接导入配置类SchedulingConfiguration,这个类注解了@Conligurntion,且注册了一ScheduledAnnotationProcesor的 Bean,源码如下:

返回ScheduledAnnotationBeanPostProcessor对象

@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class Schedulingconfiguration{

@Bean(name=TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor(){
return new ScheduledAnnotationBeanPostProcessor();
    }
}

第二类:依据条件选择配置类

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
publie @intertace EnableAsync{
class<? extends Annotation> annotation () default Annotation.class;
boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;
}

AsyncConfigurationSelector 通过条件来选择需要导入的配置AsyncConfigurationSelector 的根接口为ImportSelector,这个接口需重写selectImpors方此方法内进行事先条件判断,此例中,若adviceMode为PORXY,则返回ProxyAsyncConfiguration 这个配置类:若 activeMode 为 ASPECTJ,则返回AspectJAsyncConfiguration配置类,源码如下:

public class AsyncconfigurationSelector extends  AdviceModeImportSelector<EnableAsync> {

        private static final String ASYNC_BXBCUTION_ ASPECT_ CONPIGURATION_CLASS_NANME=

        "org.springframework.scheduling.aspectj.AspectJAsyncConfiguratlon";

@Override
public String[] selectImports(AdviceMode adviceMode){
       switch(adviceMode)(
        case PROXY:
        return new String[] {ProxyAsyncConfiguration.class.getName()};
        case ASPECTJ:
        return new String[]
        { ASYNC_EXECUTION_ ASPECT_CONFIGURATION_CLASS_NAME };
        default:
            return null;
        }
    }
}

第三类:动态注册Bean

@Target (ElementType.TYPE)
@Retention (RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass () default false;
}

AspectlAutoProxyRegistar 实现了ImportBeanDefinitionRegistrar 接口,ImportBeanDefinitionRegistrar的作用是在运行时自动添加Bean到己有的配置类,通过重写方法:
registerBeanDefinitions (AnnotationMetadata importingClassMetadata,BeanDefinitionRegistry registry)
其中,AnnotationMetadata 参数用来获得当前配置类上的注解,BeanDefinitionRegistry 参数用来注册Bean、源码如下:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata  importingClassMatadata , BeanDefinitionRegistry  registry){ 

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

AnnotationAttributes enableAJAutoProxy=
AnnotationConfigUtils.attributesFor(importingClassMetadata,EnableAspectJAutoProxy.class);
if (enableAJAutoProxy.getBoolean("proxyTargetClass")){
        AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
        }
    }
}

这个内容有点不是很实用了,但是深入这些源码可以对@Enable类型的注解有深入的了解和熟悉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值