spring组件注册系列注解源码详解

前言

spring注解开发的组件注册可以完全使用注解来做到,舍弃了传统的xml配置文件,取而代之的是使用配置类来设置配置信息

@Configuration

此注解标注在类上,表名该类为配置类,配置类的作用和配置文件一样。

@Bean

该注解可标注在方法上,容器初始化时将调用该方法,并将该方法的返回值注入到容器中,组件的名字默认为方法名。
如果显式的指定了组件名称,方法名将被忽略

@AliasFor("name")
	String[] value() default {};

用于设置要被注入的组件的名字,作用同name属性
2.

 boolean autowireCandidate() default true;

用于设置该组件是否会被自动装配到其他组件中
3.

 String initMethod() default "";

用于设置该组件的初始化方法

@ComponentScan

该注解用于指定要扫描的包,容器将会注入被扫描的包中的被标记的组件。
该注解可以在一个配置类上多次标注

@AliasFor("basePackages")
	String[] value() default {};

用于指定要扫描的包名,作用同basePackages属性

`Class<?>[] basePackageClasses() default {};

将会扫描指定类所在的包

boolean useDefaultFilters() default true;

指示是否使用默认的过滤器,在使用默认过滤器的情况下,将会把被扫描的包中的所有被@Controller、@Service、@Repository、@Component标注的类注入到容器

在该注解内部,定义了一个内部注解@Filter,用于匹配要注入的组件。

@interface Filter {
		//FilterType是一个枚举类型。用于指定匹配模式,默认是按注解匹配
		FilterType type() default FilterType.ANNOTATION;
		//用于指定将要被当作过滤器的类
		@AliasFor("classes")
		Class<?>[] value() default {};
		@AliasFor("value")
		Class<?>[] classes() default {};
		/*此属性为tpye属性服务。若type属性被设置为AspectJ
		此值应为AspectJ表达式;若type属性被设置为REGEX,此值应为
		正则表达式*/
		String[] pattern() default {};
	}

type属性有5种取值,其中最为常用的有

  • FilterType.ANNOTATION, 按注解匹配
  • FilterType.ASSIGNABLE_TYPE,按类类型匹配
  • FilterType.CUSTOM, 自定义匹配模式,需要自己写一个实现了TypeFilter接口的类

下面将分别演示

假如我们现在需要将所有被@MyAnnotation标注的组件注入容器,可以这样来写@Filter注解:

@Filter(classes=MyAnnotation.class, type=FilterType.ANNOTATION)

假如我们将所有MyClass类型及其子类都注入容器,可以这样写:

@Filter(type=FilterType.ASSIGNABLE_TYPE, classes=MyClass.class)
 Filter[] includeFilters() default {};

指定过滤器,这些过滤器匹配到的组件将被注册进容器。与此属性作用相反的属性为Filter[] excludeFilters() default {};

@Scope

用于设置组件的作用域

@AliasFor("scopeName")
	String value() default "";

该属性的取值有4个

  • singleton 单实例,默认值,默认情况下在容器生成时立即注入
  • prototype 多实例 默认情况下在从容器中获取该组件时,才会注入该组件到容器,且每次获取都会创建一个新对象注入容器(懒加载)
  • request 一次请求创建一个实例(不常用)
  • session 一个session创建一个实例(不常用)

@Lazy

boolean value() default true;

用于设置组件是否是懒加载的,默认是是的

@Conditional

此注解在springBoot中应用十分广泛,用于有条件的注入组件
它可以标注在类上,也可标注在方法上
@Conditional注解仅有一个属性Class<? extends Condition>[] value();用于指定条件判断类

我们创建一个实现了Condition接口的类,重写其中的boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);方法

对于被此注解标注的每一个将要注入的组件,都会使用此方法判断是否满足条件

@Import

标注在类上,它仅有一个属性:

/**
	 * {@link Configuration @Configuration}, 
	 * {@link ImportSelector},
	 * {@link ImportBeanDefinitionRegistrar}, 
	 * or regular component classes to import.
	 */
	Class<?>[] value();

注释表明:既可以传入一个配置类,也可传入一个实现了ImportSelector接口的类,或者是实现了ImportBeanDefinitionRegistrar接口的类,或者是直接传入要注入的组件的class

其中最为常用的是传入一个实现了ImportSelector接口的类,这个接口有个String[] selectImports(AnnotationMetadata importingClassMetadata);此方法的返回值便是要导入的组件的全类名

FactoryBean

首先我们可以创建一个实现了FactoryBean接口的类,充当bean工厂
该接口有如下方法:

    @Nullable
	T getObject() throws Exception;
	@Nullable
	Class<?> getObjectType();
	default boolean isSingleton() {
		return true;
	}

第一个getObject方法的返回值将会被注册进容器,第二个getObjectType方法的返回值为该工厂注册的bean的class,第三个方法控制注入的bean是单例还是多例。默认是单例的。

我们将工厂bean注入进容器后,再用该工厂bean的id获取组件,获取的组件并不是该工厂bean本身,而是该工厂bean生产的组件。如果想要获得工厂bean本身,需要在id前面加上&。
示例:
工厂bean定义:

public class ColorFactory implements FactoryBean<Color> {
    @Override
    public Color getObject() throws Exception {
        return new Color("red");
    }

    @Override
    public Class<?> getObjectType() {
        return Color.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

工厂bean所注入的组件的定义:

public class Color {
    public String type;

    public Color(String type) {
        this.type = type;
    }
}

将工厂bean注入容器:

    @Bean
    public ColorFactory colorFactory(){
        return new ColorFactory();
    }

测试代码:

 public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        System.out.println(
        context.getBean("colorFactory").getClass().getName());
        System.out.println(
        context.getBean("&colorFactory").getClass().getName());
    }

测试结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值