JavaConfig与常见Annotation(必知必会系列)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 上一篇我们介绍了 Spring中Bean的生命周期,这一篇我们接着学习在Spring Boot中的一些常用注解。

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

JavaConfig

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

例如:teacherService类,通过XML配置如下:

<bean id="teacherService" class="com.jay.spring.configuration.TeacherServiceImpl"></bean>

通过JavaConfig 配置就是这样的:

@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的实例。

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

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

@Configuration
//可以同时导入多个配置文件,比如:@Import({A.class,B.class})
@Import(TeacherConfiguration.class)
public class StudentConfiguration {
    @Bean
    public StudentService studentService(TeacherService teacherService) {
        return new StudentServiceImpl(teacherService);
    }
}

StudentServiceImpl 类中如下所示:

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三种使用方式:

直接导入普通的Java类。

配合自定义的ImportSelector使用。

配合ImportBeanDefinitionRegistrar使用。

@Conditional

@Conditional注解表示满足某种条件之后才开始初始化一个Bean或者启动某些配置,它一般用在由@Component、@Service、@Configuration等注解标识的类上面,或者由@Bean标记的方法上。如果一个@Configuration类标记了 @Conditional,则该类中所有标识了@Bean的方法和@Import注解导入的相关类将遵从这些条件。

如果我们需要自定义自己的条件类,所要做的就是实现Condtition接口,并覆盖它的matches()方法。

下面举栗子说明下,

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的时候,可以使用这个自定义条件类:

@Conditional(JdbcTemplateCondition.class)
@Service
public class JdbcDemoService {
}

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

在SpringBoot中还有一些有意思的条件注解。

7ea8d6d176e483d6b6c90b13117f9e99_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ1MzQ4MDg=,size_16,color_FFFFFF,t_70.png

@ConfigurationProperties与@EnableConfigurationProperties

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

// 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方法,但是实际开发中这个是必须的,否则无法成功注入。

@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注解。


元注解:可以注解到别的注解上的注解。

组合注解:被注解的注解我们就称之为组合注解。

@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配置文件中的节点的配置关系,接着就是介绍了各种常用的注解。希望对读者们有所帮助。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
SQL 存储 分布式计算
Hive数据仓库设计与优化策略:面试经验与必备知识点解析
本文深入探讨了Hive数据仓库设计原则(分区、分桶、存储格式选择)与优化策略(SQL优化、内置优化器、统计信息、配置参数调整),并分享了面试经验及常见问题,如Hive与RDBMS的区别、实际项目应用和与其他组件的集成。通过代码样例,帮助读者掌握Hive核心技术,为面试做好充分准备。
1177 0
|
人工智能 前端开发 JavaScript
房屋租赁|基于JavaWeb实现一个房屋租赁平台系统
本系统基于JavaWeb开发实现了一个在线房屋租赁平台系统。系统前端用户实现用户注册登录、查看房源信息、在线租赁、签定合同、在线留言、查看新闻等相关功能。后台管理员主要实现对相关信息的基本数据管理,完成用户管理、房源管理、房型管理、新闻管理、租赁管理、合同管理、系统管理、轮播图和友情链接管理等。#计算机毕业设计
709 0
|
7月前
|
C语言 C++ 容器
【数据结构】二叉搜索树(二叉排序树)
本文介绍了二叉搜索树(Binary Search Tree, BST)的定义、实现及其性能分析。二叉搜索树是一种特殊的二叉树,其特点是左子树所有节点值小于根节点值,右子树所有节点值大于根节点值,且每个子树也满足此特性。文中详细讲解了BST的节点结构、插入、查找、删除等操作的实现,并通过C++代码展示了这些功能。此外,还讨论了BST的性能:在理想情况下,时间复杂度接近O(logN),但在最坏情况下可能退化为O(N)。为了提高效率,后续将学习自平衡二叉搜索树如AVL树和红黑树。掌握BST有助于理解STL中的set和map容器。感谢阅读,欢迎点赞支持。
484 9
|
12月前
|
存储 关系型数据库 MySQL
MySQL如何备份?
【10月更文挑战第2天】MySQL如何备份?
1035 3
|
存储 文件存储
DAS和NAS的性能对比?
【6月更文挑战第29天】DAS和NAS的性能对比?
356 4
|
SQL 存储 分布式计算
MaxCompute 入门:大数据处理的第一步
【8月更文第31天】在当今数字化转型的时代,企业和组织每天都在产生大量的数据。有效地管理和分析这些数据变得至关重要。阿里云的 MaxCompute(原名 ODPS)是一个用于处理海量数据的大规模分布式计算服务。它提供了强大的存储能力以及丰富的数据处理功能,让开发者能够快速构建数据仓库、实时报表系统、数据挖掘等应用。本文将介绍 MaxCompute 的基本概念、架构,并演示如何开始使用这一大数据处理平台。
1699 0
|
缓存 负载均衡 算法
C++如何实现一致性算法
一致性哈希是一种用于分布式系统的负载均衡算法,旨在减少服务器增减导致的数据迁移。当有N台服务器时,通过哈希环将请求均匀分布到每台服务器,每台处理N/1的请求。若使用缓存如Redis,可进一步处理高并发场景。算法将哈希值空间视为环形,服务器和请求哈希后定位到环上,按顺时针方向找到第一台服务器作为负载目标。提供的C++代码实现了MD5哈希函数,以及一致性哈希算法的物理节点、虚拟节点和算法本身,以实现节点的添加、删除和请求映射。
143 1
C++如何实现一致性算法
|
API Java 数据库连接
从平凡到卓越:Hibernate Criteria API 让你的数据库查询瞬间高大上,彻底告别复杂SQL!
【8月更文挑战第31天】构建复杂查询是数据库应用开发中的常见需求。Hibernate 的 Criteria API 以其强大和灵活的特点,允许开发者以面向对象的方式构建查询逻辑,同时具备 SQL 的表达力。本文将介绍 Criteria API 的基本用法并通过示例展示其实际应用。此 API 通过 API 构建查询条件而非直接编写查询语句,提高了代码的可读性和安全性。无论是简单的条件过滤还是复杂的分页和连接查询,Criteria API 均能胜任,有助于提升开发效率和应用的健壮性。
396 0
|
安全 算法 关系型数据库
线程安全--深入探究线程等待机制和死锁问题
线程安全--深入探究线程等待机制和死锁问题
406 1
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的远程在线诊疗系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的远程在线诊疗系统的详细设计和实现(源码+lw+部署文档+讲解等)
250 0