Spring Boot实战读书收获

第三章

Spring Aware

Spring的依赖注入的最大亮点就是所有的bean对Spring容器的存在是没有任何意识的,即你可以将你的容器替换成别的容器,如Google Guice,这时Bean之间的耦合度很低。
但是在实际项目中,我们不可避免的要使用到Spring容器本身的功能资源,这个时候就需要Bean必须要意识到Spring容器的存在,只有这样才能够调用Spring所提供的资源,这就是所谓的Spring Aware。但是使用了Spring Aware,我们的Bean就会和Spring框架耦合。
Aware接口的子接口如图所示。
在这里插入图片描述
其中常用的接口和相关作用如下表所示。

接口名称作用
BeanNameAware获得到容器中Bean的名称
BeanFactoryAware获得当前bean factory,这样可以调用容器的服务
ApplicationContextAware获取当前的application context,,这样可以调用容器的服务
MessageSourceAware获取message source,这样可以获得文本信息
ApplicationEventPublisherAware应用事件发不起,可以发布事件
ResourceLoaderAware获得资源加载器,可以加载外部资源文件。

Spring Aware的目的是为了让Bean获得Spring容器提供的服务,因为ApplicationContext接口集成了MessageSource、ApplicationEventPublisher、ResourceLoader等接口,所以Bean实现ApplicationContextAware接口就可以获得Spring容器的所有服务,但原则上我们还是用到什么接口,就实现什么接口。

@Enable*注解的工作原理

Spring和Spring Boot提供了很多Enable注解。我们通过简单的@Enable来开启一项功能的支持,从而避免自己配置大量的代码,大大降低使用难度。
通过观察@Enable*的源码,我们发现所有的注解都有一个@Import注解。

@Import注解是用来导入标注@Configuration的类,作用和在Spring XML中的import标签一样,除此之外,该注解还可以用来导入ImportSelector、ImportBeanDefinitionRegistrar的实现类和regular component class。

@Import是用来导入配置类的,这也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean。这些导入的配置方式主要分为以下三种类型。

第一类:直接导入配置类(@Configuration)

eg: @EnableScheduling

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

直接导入配置类SchedulingConfiguration,这个类注解了@Configuration,且注册了一个ScheduledAnnotationBeanPostProcessor的Bean。

@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {

	@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
		return new ScheduledAnnotationBeanPostProcessor();
	}
}

第二类:依据条件选择配置类(@ImportSelector)

eg: @EnableAsync

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AsyncConfigurationSelector.class})
public @interface EnableAsync {
    Class<? extends Annotation> annotation() default Annotation.class;

    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}

AsyncConfigurationSelector通过条件来选择需要导入的配置类,AsyncConfigurationSelector的根接口是ImportSelector,这个接口包含一个selectImports方法,实现类也是通过重写该方法来实现有选择的加载配置类。SpringBoot中的@EnableAutoConfiguration就是这一类。

第三类:动态注册Bean(@ImportBeanDefinitionRegistrar)

eg: @EnableAspectJAutoProxy

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}

AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,该接口的作用是在运行时自动添加Bean到已有的配置类中,通过重写方法:

public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);

其中AnnotationMetadata参数是用来获得当前配置类上的注解,BeanDefinitionRegistry参数用来注册Bean。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值