@Async

https://www.cnblogs.com/wlandwl/p/async.html(已写demo)
简单总结:

  1. 为方法加上@Async注解后,可使方法异步执行,其中有返回值的方法需要返回Future
  2. 为需要调用这些方法的类加上@EnableAsync之后,这些类通过DI注入上述可异步执行方法的实例后,即可异步执行被标记方法
  3. 重写异步方法使用的线程池见文中的三种方法

    @Slf4j

    在类中使用,会为类中注入一个神奇的log对象,实际就是以类为参数的LoggerFactory.getLogger()拿到的logger。
    这是lombok的奇技淫巧之一。

@PathVariable

用于解析可变url中的信息,Code explains itself.

  1. @GetMapping("/deleteUser/{id}")
  2. public String deleteUser(
  3. @PathVariable("id")/*当入参名称与路径声明名称一致时,可省略该参数*/ String id) {
  4. return id + " deleted";
  5. }

@Profile

用于为Bean类和方法配置不同的环境,以使得其仅在对应的环境中才会加载

修饰位置

@Profile可用于修饰类、方法和注解

  1. 可以修饰@Component@Configuration注解所修饰的类(也即会被自动绑定的Bean)
  2. 可以修饰在@Configuration注解所修饰的配置类中,产生Bean的方法,原理与1.类似
  3. 可以修饰自定义注解,这使得该注解修饰的类有对应@Profile的功能

    作用

    Environment与Profiles的概念见:https://www.yuque.com/riseuplzy/gl3gpl/mnvwhf

总之:@Profile的作用就是为不同环境配置不同BeanDefinition

使用

为spring应用配置环境可以在application.properties/yaml中进行配置:

  1. spring.profiles.active=dev

或是在spring应用启动的Java选项中,添加上述的双杠(—)配置
使用配置是,要给出指定的profile信息:

  1. @Component
  2. @Slf4j
  3. @Profile("pre")
  4. public class PreBean {
  5. @PostConstruct
  6. public void init() {
  7. log.warn(getClass().getName()+" is loaded in pre env");
  8. }
  9. }

另外,可以还可以定义application-{profile}.properties/yml,来为指定profile生成配置文件

@DeclareParents

这个注解用于实现spring的AOP中,mixin模式的功能增强,其定义如下:

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.FIELD)
  3. public @interface DeclareParents {
  4. String value();
  5. Class defaultImpl() default DeclareParents.class;
  6. }

一般,这个注解用于被@Aspect注解的Interceptor类的字段中,并且该字段应被声明为接口类型。
其中,value用于指定被加上注解的字段的类型被“附加到”哪个类上,而defaultImpl用于指定这个类型的默认实现方法,也即增强方法的具体实现,例子:

  1. @Aspect
  2. @Component
  3. public class AdderInterceptor implements Ordered {
  4. @DeclareParents(value = "com.example.learn.spring.aop.AopEntity",defaultImpl = TestServiceImpl.class)
  5. public TestService testService;
  6. @Override
  7. public int getOrder() {
  8. return 2;
  9. }
  10. }

如此,通过Spring拿到的AopEntity类型的实例(实际上已经被AOP机制转换为代理对象)就能够被强制转换为TestService,并顺势调用在上述Interceptor注解的实现类的方法,这样就相当于为AopEntity类对象提供了TestService的能力:

  1. @Component
  2. public class Runner implements ApplicationRunner {
  3. @Resource
  4. private AopEntity aopEntity;
  5. @Override
  6. public void run(ApplicationArguments args) throws Exception {
  7. ((TestService)aopEntity).methodInTestService();
  8. }
  9. }

这样就能够通过AOP实现功能增强;另外,如果为TestService创建切面,使用target方法不会关联到AopEntity中其他的方法,因为target方法基于类型判别,而AopEntity本身并不instanceof TestService;但是使用this方法则能够把切面加到AopEntity的所有方法上,因为this方法语义被Spring扩展,它基于对象实体层面判别,而经过JDK动态代理后的对象既instanceof AopEntity,又instanceof TestService,所以它的所有方法都会被代理,具体可见我另一篇文章:https://www.yuque.com/riseuplzy/gl3gpl/tlc8ya