Springboot中的自动装载与初始化

Springboot中的自动装载

ImportSelector

ImportSelector接口是Spring导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableXXX(功能性注解)中起到了决定性作用。当在@COnfiguration标注的Class上使用@Import引入了一个ImportSelector实现类后,会把实现类中返回的Class名称都定义为bean

手动实现自动装载代码

创建一个测试module

跳过解释,直接创建出来不需要做任何配置

创建一个需要被自动装载的对象

假设我们有一个User对象需要被装载,创建这个对象。

@Data 只是实现了对象getter/setter/toString/构造方法的自动编写而已

@Data
public class User {
    private String username;
    private Integer age;
}

创建一个对象配置类

对上面创建的User对象进行初始化和配置。

这里对user对象设置了一些属性值,并return该设置好的user

注意: userConfiguration这个类没有被任何注解标注,表示他开始不会被容器夹在进来,即使getUser作为@Bean被注解了。这个bean也不会马上加载进入容器。

public class UserConfiguration {
    @Bean
    public User getUser() {
        User user = new User();
        user.setUsername("asdfas dfas");
        user.setAge(11);

        return user;
    }
}

创建一个ImportSelector类

最简单的实现,实现了 ImportSelector接口,并重写接口方法selectImports

这里面返回字符串数组,直接返回了我需要返回的配置类UserConfiguration

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

public class UserImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{UserConfiguration.class.getName()};
    }
}

创建一个EnableXXX注解

创建进入外部对象的注解 EnableUserBean

需要加的注解(参照其他EnableXXX标签的实现)

  1. @Retention(RetentionPolicy.RUNTIME) : 通过运行时的反射机制来处理EnableUserBean注解。

  2. @Documented: 注解表明这个EnableUserBean注解应该被 javadoc工具记录。

  3. @Target(ElementType.TYPE): 说明了EnableUserBean注解所修饰的对象范围为类,接口(包括注解类型)或enum声明。

  4. @Import(UserImportSelector.class): 导入前置加载类UserImportSelector

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Import;

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import(UserImportSelector.class)
public @interface EnableUserBean {
}

#### 启动类配置自定义注解EnableXXX

这里模拟启动类写一个测试类,该测试类被@EnableUserBean标签注解,

通过AnnotationConfigApplicationContext加载容器,

然后通过容器直接去get User Bean。

如果没有@EnableUserBean注解,就应该得不到User Bean,但是通过这种方式我们获得了user bean

import cd.itcast.bean.EnableUserBean;
import cd.itcast.bean.User;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@EnableUserBean
public class TestApplication {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext sc = new AnnotationConfigApplicationContext(TestApplication.class);
        User bean = sc.getBean(User.class);
        System.out.println(bean);
    }
}

 

附录

Retention注解

注解@Retention可以用来修饰注解,是注解的注解,称为元注解。 Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型, 这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。

RetentionPolicy有3个值:CLASS RUNTIME SOURCE 按生命周期来划分可分为3类: 1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃; 2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期; 3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在; 这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。

那怎么来选择合适的注解生命周期呢? 首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。 一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解,比如@Deprecated使用RUNTIME注解 如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解; 如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,使用SOURCE 注解。

注解@Override用在方法上,当我们想重写一个方法时,在方法上加@Override,当我们方法的名字出错时,编译器就会报错 注解@Deprecated,用来表示某个类或属性或方法已经过时,不想别人再用时,在属性和方法上用@Deprecated修饰注解@SuppressWarnings用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候

Target注解

@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。

作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)

取值(ElementType)有:

  1.CONSTRUCTOR:用于描述构造器     2.FIELD:用于描述域     3.LOCAL_VARIABLE:用于描述局部变量     4.METHOD:用于描述方法     5.PACKAGE:用于描述包     6.PARAMETER:用于描述参数     7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值