SpringBoot中那些常用注解分析-2

简介: SpringBoot中那些常用注解分析-2

④ 使用@ComponentScan

如下所示,定义了@Configuration的类还可以同时使用@ComponentScan注解:

@Configuration
@ComponentScan("com.jane.app.services")
public class AppConfig {
  // various @Bean definitions ...
}

⑤ 使用Environment API

外部环境中的值可以通过注入Environment来获取,如下所示:

@Configuration
public class AppConfig {
    @Autowired 
    Environment env;
    @Bean
    public MyBean myBean() {
       MyBean myBean = new MyBean();
       myBean.setName(env.getProperty("bean.name"));
       return myBean;
    }
}

⑥ 使用@PropertySource

@PropertySource可以根据需要加载指定的配置文件(@ConfigurationProperties 默认从全局配置文件获取配置),将配置文件中的属性注入到系统环境中。

@Configuration
@PropertySource("classpath:/com/jane/app.properties")
public class AppConfig {
   @Inject 
   Environment env;
   @Bean
   public MyBean myBean() {
       return new MyBean(env.getProperty("bean.name"));
   }
}

⑦ @Value注解

⑥中我们使用env.getProperty("bean.name")来获取beanName,那么我们也可以直接使用@Value注解来获取环境中的属性。

@Configuration
@PropertySource("classpath:/com/jane/app.properties")
public class AppConfig {
  @Value("${bean.name}") 
  String beanName;
   @Bean
   public MyBean myBean() {
       return new MyBean(beanName);
   }
}

⑧ @Import注解

类似Spring XML中配置的<import>标签一样,@Configuration配置类可以使用@Import注解进行组合。

⑧ @Import注解
类似Spring XML中配置的<import>标签一样,@Configuration配置类可以使用@Import注解进行组合。
@Co

⑨ @Profile

@Configuration类可以用@Profile注解标记,以指示只有在给定的一个或多个配置文件处于活动状态时才应处理它们。

@Profile("development")
@Configuration
public class EmbeddedDatabaseConfig {
    @Bean
    public DataSource dataSource() {
        // instantiate, configure and return embedded DataSource
    }
}
@Profile("production")
@Configuration
public class ProductionDatabaseConfig {
    @Bean
    public DataSource dataSource() {
        // instantiate, configure and return production DataSource
    }
}

前面提到过,也可以在方法级别与@Bean注解一起使用,如下所示:

@Configuration
public class ProfileDatabaseConfig {
    @Bean("dataSource")
    @Profile("development")
    public DataSource embeddedDatabase() { ... }
    @Bean("dataSource")
    @Profile("production")
    public DataSource productionDatabase() { ... }
}

⑩ @ImportResource引入外部xml配置

可以使用@ImportResource注解引入外部的spring xml配置,xml中定义的bean可以自动被注入。

@Configuration
@ImportResource("classpath:/com/jane/database-config.xml")
public class AppConfig {
    @Inject 
    DataSource dataSource; // from XML
    @Bean
    public MyBean myBean() {
        // inject the XML-defined dataSource bean
        return new MyBean(this.dataSource);
    }
}

(11) 使用嵌套的@Configuration

@Configuration
public class AppConfig {
   @Inject 
   DataSource dataSource;
   @Bean
   public MyBean myBean() {
       return new MyBean(dataSource);
   }
   @Configuration
   static class DatabaseConfig {
       @Bean
       DataSource dataSource() {
           return new EmbeddedDatabaseBuilder().build();
       }
   }
}

类似于上述实例时,只需要注册AppConfig 。因为AppConfigDatabaseConfig 已经清晰,故而不需要再使用@Import(DatabaseConfig.class)

(12) Test支持

spring-test模块中的Spring TestContext framework提供了@ContextConfiguration,其可以接受一个component 类数组,通常是@Configuration或者@Component类。

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {AppConfig.class, DatabaseConfig.class})
public class MyTests {
    @Autowired MyBean myBean;
    @Autowired DataSource dataSource;
    @Test
    public void test() {
        // assertions against myBean ...
    }
}


(13) @Enable注解

使用@Enable注解使内置的Spring features 起作用,如@EnableAsync、@EnableScheduling、@EnableTransactionManagement、@EnableAspectJAutoProxy、@EnableWebMvc。

(14)@Configuration注解的一些约束


必须是类,不能是工厂方法返回的实例;

必须不能是final的,除非proxyBeanMethods设置为false;

配置类必须是非本地的(即可能不在方法中声明),native 标注的方法;

嵌套的@Configuration必须是static;

@Bean方法不能返回任何configuration 类。

【4】功能类注解

① @ControllerAdvice

① ControllerAdvice定义


一种特殊的Component类,其内部声明的@ExceptionHandler、@InitBinder或者@ModelAttribute可以被@Controller类共享。


在SpringMVC常见组件之HandlerAdapter分析中我们从源码角度分析了,当ControllerAdviceBean定义了@ExceptionHandler、@InitBinder或者@ModelAttribute方法时,其如何被应用。


声明了@ControllerAdvice注解的类可以直接被声明为Spring Bean或者通过类路径自动扫描注入。这些bean可以通过实现Ordered接口或者使用@Order/@Priority注解来进行排序,前者(实现接口)优先于后者(注解)。在系统运行时,就会根据其order值进行使用。不过值得一提的是,PriorityOrdered接口在排序上的优先级低于Ordered。当然,如果@ControllerAdvice bean被声明为一个request-scoped或者session-scoped bean,Ordered就将不那么重要。


为了处理异常,通常在第一个@ControllerAdvice bean中声明一个标注了@ExceptionHandler注解的方法。对于模型属性和数据绑定初始化,也就是@ModelAttribute和@InitBinder方法将会遵循order顺序。


对于@ExceptionHandler方法,在特定advice bean的方法中,根异常匹配比只匹配当前异常更可取。但是,与低优先级通知bean上的任何匹配(无论是根级别还是具体异常级别)相比,高优先级通知上的具体异常匹配仍然是首选的。因此,请按照相应的顺序在高优先级的advice bean上声明primary root exception映射。


默认情况下,@ControllerAdvice类的方法是全局性的,针对所有controller起作用。可以使用诸如annotations、basePackageClasses或者basePackages来定义目标范围。如果定义了多个筛选条件,那么将会以“OR”的逻辑含义起作用。这个判断逻辑可以从如下源码展示:

// org.springframework.web.method.HandlerTypePredicate#test
@Override
public boolean test(Class<?> controllerType) {
// 如果没有选择器,直接返回true
  if (!hasSelectors()) {
    return true;
  }
  // 否则根据选择器定义范围进行判断
  else if (controllerType != null) {
    for (String basePackage : this.basePackages) {
      if (controllerType.getName().startsWith(basePackage)) {
        return true;
      }
    }
    for (Class<?> clazz : this.assignableTypes) {
      if (ClassUtils.isAssignable(clazz, controllerType)) {
        return true;
      }
    }
    for (Class<? extends Annotation> annotationClass : this.annotations) {
      if (AnnotationUtils.findAnnotation(controllerType, annotationClass) != null) {
        return true;
      }
    }
  }
  return false;
}

② ControllerAdvice 源码

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
   // 定义扫描包数组
  @AliasFor("basePackages")
  String[] value() default {};
//扫描的包路径,如下所示 
// @ControllerAdvice(basePackages = "org.my.pkg")}
// @ControllerAdvice(basePackages = {"org.my.pkg", "org.my.other.pkg"})}
  @AliasFor("value")
  String[] basePackages() default {};
// 扫描的包的类型数组
  Class<?>[] basePackageClasses() default {};
// 适应的类型-controller只要符合其中一个类型,将会被作为目标对象
  Class<?>[] assignableTypes() default {};
   // 作用目标-注解类型数组。controller只要标注了数组中一个注解,将会被作为目标对象
  Class<? extends Annotation>[] annotations() default {};
}


使用@ControllerAdvice 对异常处理可以参考博文SpringMVC中异常处理与ControllerAdvice捕捉全局异常


目录
相关文章
|
5天前
|
缓存 Java Sentinel
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
|
5天前
|
运维 Java 程序员
Spring5深入浅出篇:基于注解实现的AOP
# Spring5 AOP 深入理解:注解实现 本文介绍了基于注解的AOP编程步骤,包括原始对象、额外功能、切点和组装切面。步骤1-3旨在构建切面,与传统AOP相似。示例代码展示了如何使用`@Around`定义切面和执行逻辑。配置中,通过`@Aspect`和`@Around`注解定义切点,并在Spring配置中启用AOP自动代理。 进一步讨论了切点复用,避免重复代码以提高代码维护性。通过`@Pointcut`定义通用切点表达式,然后在多个通知中引用。此外,解释了AOP底层实现的两种动态代理方式:JDK动态代理和Cglib字节码增强,默认使用JDK,可通过配置切换到Cglib
|
4天前
|
Java
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
Springboot 使用自定义注解结合AOP方式校验接口参数
|
5天前
|
存储 缓存 Java
【JavaEE】Spring中注解的方式去获取Bean对象
【JavaEE】Spring中注解的方式去获取Bean对象
3 0
|
5天前
|
存储 Java 对象存储
【JavaEE】Spring中注解的方式去存储Bean对象
【JavaEE】Spring中注解的方式去存储Bean对象
9 0
|
5天前
|
JSON 前端开发 Java
【JAVA进阶篇教学】第七篇:Spring中常用注解
【JAVA进阶篇教学】第七篇:Spring中常用注解
|
5天前
|
JavaScript Java 开发者
Spring Boot中的@Lazy注解:概念及实战应用
【4月更文挑战第7天】在Spring Framework中,@Lazy注解是一个非常有用的特性,它允许开发者控制Spring容器的bean初始化时机。本文将详细介绍@Lazy注解的概念,并通过一个实际的例子展示如何在Spring Boot应用中使用它。
21 2
|
5天前
|
前端开发 Java
SpringBoot之自定义注解参数校验
SpringBoot之自定义注解参数校验
19 2
|
5天前
|
Java Spring
springboot自带的@Scheduled注解开启定时任务
springboot自带的@Scheduled注解开启定时任务
|
5天前
|
XML JSON Java
【SpringBoot】springboot常用注解
【SpringBoot】springboot常用注解