前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaConfig与常见Annotation(必知必会)

JavaConfig与常见Annotation(必知必会)

作者头像
码农飞哥
发布2021-08-18 10:47:01
2560
发布2021-08-18 10:47:01
举报
文章被收录于专栏:好好学习

上一篇我们介绍了Spring中Bean的生命周期,这一篇我们接着学习在Spring Boot中的一些常用注解。

JavaConfig

说注解之前,我们先了解下JavaConfig。在注解方式实例化Bean之前,我们都是通过XML来配置Bean以及其依赖关系的,造成了项目中有大量的XML文件,使项目变得复杂,不便于维护。所以JavaConfig 就应运而生了,JavaConfig是Spring的一个子项目。它基于Java代码和Annotation注解来描述Bean之间的依赖绑定关系。例如:teacherService类,通过XML配置如下:

代码语言:javascript
复制
<bean id="teacherService" class="com.jay.spring.configuration.TeacherServiceImpl"></bean>

通过JavaConfig 配置就是这样的:

代码语言:javascript
复制
@Configuration
public class TeacherConfiguration {

    @Bean
    public TeacherService teacherService(){
        return new TeacherServiceImpl();
    }
}

@Configuration 注解标注在类上,相当于把该类作为Spring的XML配置文件中的 <beans>,其作用为:配置Spring容器,需要注意的是:

  1. @Configuration不可以是final类型;
  2. @Configuration 不可以是匿名类
  3. 嵌套的Configuration必须是静态类。 @Bean 注解标注方法上(返回某个实例的方法),等价于Spring的XML配置文件中的 <bean>,作用是注册bean对象,对象实例的名字默认是方法名。我们也可以通过name 属性来指定实例名。
  4. @Bean 注解默认作用域为单例singleton 作用域,可通过 @Scope(”prototype“)设置为原型作用域
  5. 既然@Bean的作用是注册bean对象,那么完全可以使用 @Component@Controller@Service@Ripository等注解注册bean,当然需要配置 @ComponentScan注解进行自动扫描。

@ComponentScan

@ComponentScan注解对应Spring的XML配置文件中的 <context:component-scan/> 表示启动组件扫描,Spring会自动扫描所有通过注解配置的bean,然后将其注册到IOC容器中,我们可以通过basePackages属性来指定 @ComponentScan自动扫描的范围,如果不指定,则默认从声明 @ComponentScan所在类的package进行扫描,正是因为如此,SpringBoot的启动类都是默认在/src/main/java下。

@Import

@Import 注解用于导入配置类,应用场景就是一个配置类中的一个Bean依赖于另一个配置类中的一个Bean。例如:下面有一个 TeacherConfiguration配置类。这个类里定义了一个TeacherService的实例。

代码语言:javascript
复制
@Configuration
public class TeacherConfiguration {
    @Bean
    public TeacherService teacherService(){
        return new TeacherServiceImpl();
    }
}

还有一个 StudentConfiguration配置类,这个配置类中定义的StudentService的实例需要依赖TeacherService对象。所以我们在 StudentConfiguration中将 TeacherConfiguration引入,如下所示:

代码语言:javascript
复制
@Configuration
//可以同时导入多个配置文件,比如:@Import({A.class,B.class})
@Import(TeacherConfiguration.class)
public class StudentConfiguration {

    @Bean
    public StudentService studentService(TeacherService teacherService) {
        return new StudentServiceImpl(teacherService);
    }
}

StudentServiceImpl 类中如下所示:

代码语言:javascript
复制
public class StudentServiceImpl implements StudentService {

    private TeacherService teacherService;

    public StudentServiceImpl(TeacherService teacherService) {
        this.teacherService = teacherService;
    }
}

@Import 注解支持导入普通java类,并将其声明成一个Bean,主要用于将多个分散的JavaConfig配置类融合成一个更大的config类。

  • @Import 注解在4.2之前只支持导入配置类。
  • 在4.2之后@Import注解支持导入普通的java类,并将其声明成一个Bean。 @Import三种使用方式:
  1. 直接导入普通的Java类。
  2. 配合自定义的ImportSelector使用。
  3. 配合ImportBeanDefinitionRegistrar使用。

@Conditional

@Conditional注解表示满足某种条件之后才开始初始化一个Bean或者启动某些配置,它一般用在由 @Component@Service@Configuration等注解标识的类上面,或者由 @Bean标记的方法上。如果一个 @Configuration类标记了 @Conditional,则该类中所有标识了 @Bean的方法和 @Import注解导入的相关类将遵从这些条件。如果我们需要自定义自己的条件类,所要做的就是实现Condtition接口,并覆盖它的 matches()方法。下面举栗子说明下,

代码语言:javascript
复制
public class JdbcTemplateCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        try {
            context.getClassLoader().loadClass("org.springframework.jdbc.core.JdbcTemplate");
            return true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return false;
    }
}

当你用Java来声明Bean的时候,可以使用这个自定义条件类:

代码语言:javascript
复制
@Conditional(JdbcTemplateCondition.class)
@Service
public class JdbcDemoService {

}

这个栗子中只有当JdbcTemplateCondition类的条件成立时才会创建JdbcDemoService这个Bean,也就是说JdbcDemoService这个Bean的创建条件是classpath里面包括JdbcTemplate,否则这个bean的声明就会被忽略掉。在SpringBoot中还有一些有意思的条件注解。

@ConfigurationProperties与@EnableConfigurationProperties

当某些属性的值需要配置的时候,我们一般会在 applcation.properties文件中新建配置项,然后通过 @Value注解来获取配置项,比如下面配置数据源的代码。

代码语言:javascript
复制
// jdbc config
jdbc.mysql.url=jdbc:mysql://localhost:3306/category
jdbc.mysql.username=root
jdbc.mysql.password=123456
//配置数据源
@Configuration
public class DataSouceConfiguration {
    @Value("jdbc.mysql.url")
    public String url;
    @Value("jdbc.mysql.username")
    public String user;
    @Value("jdbc.mysql.password")
    public String password;

    @Bean
    public DataSource dataSource() {
        DataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl(url);
        ds.setUsername(user);
        ds.setPassword(password);
        return ds;
    }
}

如果配置比较多的话,用 @Value来获取注解就比较low了,代码也不美观。没关系,我们还有个更加好用的注解 @ConfigurationProperties。这个注解可以把同类的配置信息自动封装成实体类,如上获取数据源的代码可以改写成下面这样,由于篇幅的问题这里省略了setter、getter方法,但是实际开发中这个是必须的,否则无法成功注入。

代码语言:javascript
复制
@Configuration
@ConfigurationProperties(prefix = "jdbc.mysql")
public class DataSouceConfiguration2 {

    public String url;

    public String user;

    public String password;

    @Bean
    public DataSource dataSource() {
        DataSource ds = new BasicDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl(url);
        ds.setUsername(user);
        ds.setPassword(password);
        return ds;
    }
}

@EnableConfigurationProperties 注解表示对@ConfigurationProperties的内嵌支持, 默认会将对应Properties Class作为Bean 注入到IOC容器中,即在相应的Properties 类上不用加@Component注解。

组合注解

当可能大量同时使用到几个注解到同一个类上,就可以考虑将这几个注解到别的注解上,被注解的注解我们就称之为组合注解,例如 @SpringBootApplication注解。

  • 元注解:可以注解到别的注解上的注解。
  • 组合注解:被注解的注解我们就称之为组合注解。
代码语言:javascript
复制
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

}

如上 @SpringBootApplication注解上注解了 @SpringBootConfiguration@EnableAutoConfiguration以及 @ComponentScan三个元注解。

总结

本文首先介绍了JavaConfig讲到了注解与Spring的XML配置文件中的节点的配置关系,接着就是介绍了各种常用的注解。希望对读者们有所帮助。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农飞哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • JavaConfig
  • @ComponentScan
  • @Import
  • @Conditional
  • @ConfigurationProperties与@EnableConfigurationProperties
  • 组合注解
  • 总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档