Spring framework Day15:@lmport注解使用

前言

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

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

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

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

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

一、开始学习

1、新建项目,结构如下

Spring framework Day15:@lmport注解使用_第1张图片

2、添加 spring 依赖 
 
    
    
        
        
            org.springframework
            spring-context
            5.3.23
        
 
        
            ch.qos.logback
            logback-classic
            1.4.5
        
 
    
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 所有需要导入类的完整类名
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 创建一个集合保存带有注解的类的完整类名
        ArrayList 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 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 {

    @Bean
    public 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

你可能感兴趣的:(spring,framework,spring,java,后端)