Spring framework Day15:@lmport注解使用

news/2024/11/25 13:41:34/

前言

在编程中,@import注解通常用于导入外部的类、接口或其他资源,以便在当前代码文件中使用。它可以提供一种简洁、方便的方式来引入外部依赖,并且有以下几个主要的应用场景和好处:

  1. 引入外部类/接口:使用@import注解可以将其他模块或库中的类/接口引入到当前的代码文件中,使得我们可以直接使用这些类/接口,而无需手动编写完整的类名。这样可以减少代码中的冗余,提高可读性和编码效率。

  2. 静态方法/常量引入:通过@import注解还可以引入外部类中的静态方法和常量,使得我们可以直接在当前代码文件中调用这些静态方法或使用常量,而无需每次都使用完整的类名进行访问。这样不仅简化了代码书写,还提高了代码的可读性。

  3. 展示注解@import注解也可以用于展示某个特定的注解,以便在当前代码文件中使用这个注解。这在一些特定的编程框架和库中非常常见,例如在使用 Spring 框架时,我们可以使用@import注解来导入其他配置类,从而实现依赖注入等功能。

总结来说,@import注解提供了一种便捷的方式来引入外部的类、接口、静态方法和常量,以及展示注解。它简化了代码书写、提高了可读性和编码效率,并且在一些特定的框架和库中具有特殊的用途。

一、开始学习

1、新建项目,结构如下

2、添加 spring 依赖 
 <!-- spring 的核心依赖 --><dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.23</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.5</version></dependency></dependencies>
3、在 anno 包下新建一个 MyAnno 注解类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {}

这段代码定义了一个名为MyAnno的注解。让我们一步步解析这段代码的含义:

  1. @Target(ElementType.TYPE):这行代码使用@Target注解来指定了注解的作用目标。在这里,指定的目标是ElementType.TYPE,表示该注解可以应用于类、接口(包括注解类型)或枚举类型。

  2. @Retention(RetentionPolicy.RUNTIME):这行代码使用@Retention注解来指定了注解的生命周期。在这里,指定的生命周期是RetentionPolicy.RUNTIME,表示该注解在运行时仍然可用,即可以通过反射等方式获取到该注解的信息。

  3. public @interface MyAnno:这行代码定义了一个注解类型MyAnno。通过在类上使用@interface关键字,将一个普通的接口声明为一个注解类型。

综上所述,这段代码定义了一个运行时可见的注解MyAnno,并且可以应用于类、接口或枚举类型。你可以使用这个注解来修饰类、接口或枚举类型,然后在运行时通过反射等方式获取到被注解元素的相关信息。

4、在 controller 包下新建一个 UserController 类
@Slf4j
@MyAnno
public class UserController {public void add(){log.info("添加用户");}}

这段代码为UserController类添加了@MyAnno注解和@Slf4j注解。让我们一步步解析这段代码的含义:

  1. @MyAnno:这个注解用来修饰UserController类,表示该类被注解为MyAnno类型。由于我们在MyAnno注解中指定了作用目标为类、接口或枚举类型,所以这个注解可以应用于类。

  2. @Slf4j:这个注解是 Lombok 库提供的一个注解,用来自动生成日志记录器变量log(即private static final Logger log = LoggerFactory.getLogger(UserController.class);),避免了手动编写日志记录器的繁琐过程。

  3. public class UserController:这是一个普通的 Java 类定义,表示一个名为UserController的类。

  4. public void add():这是一个方法定义,表示UserController类中的一个名为add的公共实例方法。该方法使用了@Slf4j注解生成的log变量,用来记录日志信息。

综上所述,这段代码为UserController类添加了@MyAnno注解和@Slf4j注解,并且定义了一个名为add的公共实例方法,在该方法中调用了自动生成的日志记录器变量log记录日志信息。

5、在 config 包下新建 Annoimportlector 配置类
/*** @Date 2023-10-08* @Author qiu* 自定义导入选择器,如果类上标注了 @MyAnno 的注解,* 就将其纳入 Spring 容器中管理*/
public class AnnoimportSelector implements ImportSelector {/**** @param importingClassMetadata* @return 所有需要导入类的完整类名*/@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {// 创建一个集合保存带有注解的类的完整类名ArrayList<String> classNameList = new ArrayList<>();// 解析类上是否存在 @MyAnno注解if (UserController.class.isAnnotationPresent(MyAnno.class)){classNameList.add(UserController.class.getName());}return StringUtils.toStringArray(classNameList);}
}

这段代码定义了一个名为AnnoimportSelector的类,实现了ImportSelector接口。让我们一步步解析这段代码的含义:

  1. public class AnnoimportSelector implements ImportSelector:这是一个类定义,表示一个名为AnnoimportSelector的类,实现了ImportSelector接口。

  2. @Override:这个注解表示该方法是对父类或接口中同名方法的重写。

  3. public String[] selectImports(AnnotationMetadata importingClassMetadata):这是一个方法定义,实现了ImportSelector接口中的selectImports方法。该方法的作用是根据指定的条件选择需要导入的类,并以完整类名的形式返回。

  4. ArrayList<String> classNameList = new ArrayList<>();:这行代码创建了一个ArrayList集合,用于保存带有@MyAnno注解的类的完整类名。

  5. if (UserController.class.isAnnotationPresent(MyAnno.class)):这行代码判断UserController类是否存在@MyAnno注解。如果存在,则将UserController类的完整类名添加到classNameList集合中。

  6. return StringUtils.toStringArray(classNameList);:这行代码将classNameList集合转换为字符串数组,并作为selectImports方法的返回值。

综上所述,这段代码定义了一个自定义的导入选择器AnnoimportSelector,用于根据条件选择需要导入的类。在该选择器中,如果某个类标注了@MyAnno注解,则将其纳入Spring容器中进行管理。

 6、在 config 包下新建一个 AppConfig 配置类

不使用 @Import 注解实现调用 UserService 的方法

@Configuration
public class AppConfig {@Beanpublic UserController userController(){return  new UserController();}}

在该配置类中使用@Bean注解定义了一个名为userController的Bean,该Bean是UserController类的实例。通过这种方式,我们告诉Spring容器在启动时创建并管理这个UserController的实例,从而可以在其他地方通过依赖注入的方式使用它。

7、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserController bean = context.getBean(UserController.class);bean.add();}}

 运行结果

二、使用 @Import 注解

1、 使用 @Import 注解导入(装配)普通的 bean

更改 AppConfig 配置类

@Configuration
@Import(UserController.class)
public class AppConfig {}

 在该配置类中使用@Import注解将UserController类导入到该配置类中进行管理。通过这种方式,我们告诉Spring容器在启动时创建并管理这个UserController的实例,从而可以在其他地方通过依赖注入的方式使用它。

1)、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserController bean = context.getBean(UserController.class);bean.add();}}

 运行结果

2、使用 @Import 注解导入其他的配置类(常用)
1)在 config 包下新建 MvcConfig、MybatisConfig 配置类

MvcConfig 配置类

@Configuration
public class MvcConfig {
}

 MybatisConfig 配置类

@Configuration
public class MybatisConfig {
}
2)更改 AppConfig 配置类 
@Configuration
@Import({MvcConfig.class,MybatisConfig.class,UserController.class})
public class AppConfig {}

 在该配置类中使用@Import注解将MvcConfigMybatisConfigUserController三个类导入到该配置类中进行管理。通过这种方式,我们告诉Spring容器在启动时创建并管理这些类的实例,从而可以在其他地方通过依赖注入的方式使用它们。这个配置类可以用于配置Spring MVC框架、MyBatis框架以及UserController类等相关的Bean。

 3)、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserController bean = context.getBean(UserController.class);bean.add();}}

 运行结果

3、 使用 @Import 注解实现选择性导入(即按照指定的逻辑来导入相关的类)

要实现选择性导入,可以使用@Import注解配合Condition接口来定义逻辑。

首先,创建一个实现Condition接口的自定义条件类,例如MyCondition

public class MyCondition implements Condition {@Override 
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 
// 在这里编写自定义的逻辑判断条件// 返回true表示满足条件,需要导入相关类;返回false表示不满足条件,不导入相关类// 可根据实际需求进行逻辑的判断与处理 return true; 
} }

然后,在@Import注解中使用自定义条件类:

@Configuration
@Import(value = {MvcConfig.class, UserController.class, MyConfiguration.class}) 
public class AppConfig { 
// ... 
}

在上述代码中,我们将MvcConfigUserControllerMyConfiguration类作为参数传递给@Import注解。对于需要选择性导入的类,可以根据自定义的条件类来决定是否导入。

最后,将自定义条件类注册到Spring容器中:

@Configuration 
public class MyConfiguration { 
@Bean 
public MyCondition myCondition() {return new MyCondition(); 
} 
}

这样,当MyCondition条件满足时,相关类会被导入到AppConfig配置类中进行管理,否则不会被导入。通过编写自定义的条件类,我们可以根据实际需求灵活地实现选择性导入。

三、使用 @Import 的好处

使用@Import注解的好处包括:

  1. 简化配置:通过@Import注解,可以将多个类一次性导入到配置类中进行管理,避免了在配置类中逐个声明依赖的繁琐过程,使得配置更加简洁、清晰。

  2. 组织代码结构:@Import注解可以帮助将相关的类组织在一起,提高代码的可读性和可维护性。通过将相关的类一起导入到配置类中,可以更好地表示它们之间的关联。

  3. 提供依赖注入支持:导入的类会交给Spring容器进行管理,可以通过依赖注入的方式在应用程序的其他地方使用。这样可以方便地使用这些类的实例,而无需手动创建和管理它们。

  4. 可选择性导入:@Import注解可以与自定义条件类(实现Condition接口)结合使用,根据特定的条件来决定是否导入相关的类。这种灵活性可以根据实际需求进行选择性导入,提高系统的可配置性和扩展性。

  5. 模块化开发:@Import注解可以帮助将不同模块的配置类组合在一起,实现模块化开发。通过导入其他模块的配置类,可以在一个配置类中同时配置多个模块,提供更好的代码组织和模块可复用性。

总之,@Import注解是一个强大的工具,可以简化配置、提供依赖注入支持,并且具有选择性导入和模块化开发的优势。它使得应用程序的配置更加灵活、简洁和可读,提高开发效率和代码质量。

四、总结

 本章节主要讲了 @Import 注解的三种使用:

  1、使用 @Import 注解导入(装配)普通的 bean
  例如:@Import(UserController.class)
 
 2、使用 @Import 注解导入其他的配置类(常用)
  例如:在项目中可以模块化配置类,包括 MVC 的配置类
  mybatis 配置类,Redis 配置类、Rabbit MQ 配置类等等,
  那么可以在一个总配置类中导入其他这些配置类进行合并,
  这样维护性扩展性更强
 例如:@Import({MvcConfig.class,MybatisConfig.class})
 
 3、使用 @Import 注解实现选择性导入(即按照指定的逻辑来导入相关的类)
 这种方式需要自定义一个导入选择器交给 spring 执行

五、gitee 案例

案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git


http://www.ppmy.cn/news/1155369.html

相关文章

P34~36第八章相量法

8.1复数 复数可表示平面矢量、也可表示正弦量。特别是: 当复数表示正弦量的时候&#xff0c;此时复数称为相量。 8.2复数运算 复数除法也可看做乘法&#xff0c;乘法的几何意义是旋转&#xff08;辐角相加&#xff09;( e^x e^y e^xy)&#xff0c;同时伸缩&#xff08;模变…

【C++】string

string相关 这些构造函数其中常用的有&#xff1a;第一个无参构造&#xff0c;第二个拷贝构造&#xff0c;第四个字符串初始化&#xff0c;第六个使用n个字符c初始化。 其他几个构造可以了解&#xff0c;比如第三个&#xff1a;拷贝某个字符串&#xff0c;从pos位置开始拷贝&am…

XML外部实体注入攻击XXE

xml是扩展性标记语言&#xff0c;来标记数据、定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义&#xff08;可选&#xff09;、文档元素&#xff0c;一般无法直接打开&#xff0c;可以选择用excl或记事本打…

卡尔曼家族从零解剖-(01)预备知识点

讲解关于slam一系列文章汇总链接:史上最全slam从零开始&#xff0c;针对于本栏目讲解的 卡尔曼家族从零解剖 链接 :卡尔曼家族从零解剖-(00)目录最新无死角讲解&#xff1a;https://blog.csdn.net/weixin_43013761/article/details/133846882 文末正下方中心提供了本人 联系…

codesys【手轮】

一般4线&#xff0c;也有6线 电压&#xff1a;DC5v&#xff0c;12v&#xff0c;24v 脉冲当量&#xff1a;一圈100脉&#xff0c;25脉 计数器不能【-1000】【1000】 因为一循环会多一个计数 要【-1000】【999】或者【-999】【1000】 PLC计数案例&#xff1a; // QQ750273008…

Qt creator下载安装

版本问题&#xff1a; Qt4的开发环境包括3个基本部分&#xff1a;Qt Framework&#xff08;Qt库&#xff09;、QtCreator&#xff08;IDE&#xff09;和MinGW&#xff08;编译调试&#xff09;&#xff0c;都要分别下载安装并配置&#xff0c;比较麻烦。 Qt5之后&#xff0c;…

主流接口测试框架对比

公司计划系统的开展接口自动化测试&#xff0c;需要我这边调研一下主流的接口测试框架给后端测试&#xff08;主要测试接口&#xff09;的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求&#xff0c;看哪个框架更适合我们。 需求 1、接口编写…

一键部署开源AI(人工智能对话模型)(支持显卡或CPU加内存运行)--ChatGLM2-6B

一、基本介绍&#xff1a; ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本&#xff0c;在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上&#xff0c;ChatGLM2-6B 引入了如下新特性&#xff1a; 更强大的性能&#xff1a; 基于 ChatGLM 初代模…