Spring中一些类的使用理解
1、ImportBeanDefinitionRegistrar接口
该接口用来实现动态注入Bean,可以实现该接口,但是还要利用@Import进行导入才能实现Bean的注入。使用示例如下:
定义一个注解:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Repeatable(EnableJedisClusterClients.class) @Import(JedisClusterClientRegistrar.class) public @interface EnableJedisClusterClient { String namespace() default "default"; }
然后实现该接口中的方法:
public class JedisClusterClientRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean processed = false; { AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata .getAnnotationAttributes(EnableJedisClusterClient.class.getName())); if (attributes != null) { dealOne(registry, attributes); processed = true; } } { AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata .getAnnotationAttributes(EnableJedisClusterClients.class.getName())); if (attributes != null) { AnnotationAttributes[] annotationArray = attributes.getAnnotationArray("value"); if (annotationArray != null && annotationArray.length > 0) { for (AnnotationAttributes oneAttributes : annotationArray) { dealOne(registry, oneAttributes); processed = true; } } } } if (!processed) throw new IllegalStateException("no @EnableJedisClusterClient or @EnableJedisClusterClients found! pls check!"); } private void dealOne(BeanDefinitionRegistry registry, AnnotationAttributes oneAttributes) { String namespace = oneAttributes.getString("namespace"); Assert.isTrue(StringUtils.isNotEmpty(namespace), "namespace must be specified!"); BeanRegistrationUtil.registerBeanDefinitionIfBeanNameNotExists(registry, namespace + JedisClusterClient.class.getSimpleName(), JedisClusterClientFactoryBean.class); }
在启动类上添加该注解,在SpringApplication启动时注入Bean:
@EnableJedisClusterClient(namespace = "shua-day-walk") @EnableRocketMQConsumer(namespace = OrderPaySuccessConsumer.ORDER_PAY_SUCCESS_CONSUMER) @EnableDataSource(namespace = "shua-day-walk",mapperPackages = "com.coohua.day.walk.mapper") @EnableScheduling @EnableAsync public class ShuaDayWalkApplication { public static void main(String[] args) { SpringApplication.run(ShuaDayWalkApplication.class, args); }
2、ApplicationContextAware接口
该接口主要有一个方法,就是为了将ApplicationContext设置到实现类中,从而可以让实现类对整个容器进行相应操作,但是实现类只有在被加载时,Spring才会自动调用设置方法。使用示例如下:
public class CustomizedConfigurationPropertiesBinder implements ApplicationContextAware { private ConfigurableApplicationContext applicationContext; private PropertySources propertySources; private Binder binder; public void bind(String configPrefix, Bindable<?> bean) { BindHandler handler = new IgnoreTopLevelConverterNotFoundBindHandler(); this.binder.bind(configPrefix, bean, handler); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = (ConfigurableApplicationContext) applicationContext; this.propertySources = this.applicationContext.getEnvironment().getPropertySources(); this.binder = new Binder(getConfigurationPropertySources(), getPropertySourcesPlaceholdersResolver(), getConversionService(), getPropertyEditorInitializer()); } private Iterable<ConfigurationPropertySource> getConfigurationPropertySources() { return ConfigurationPropertySources.from(this.propertySources); } private PropertySourcesPlaceholdersResolver getPropertySourcesPlaceholdersResolver() { return new PropertySourcesPlaceholdersResolver(this.propertySources); } private ConversionService getConversionService() { return this.applicationContext.getBeanFactory().getConversionService(); } private Consumer<PropertyEditorRegistry> getPropertyEditorInitializer() { return this.applicationContext.getBeanFactory()::copyRegisteredEditorsTo; } }
实现类的加载:定义Configuration,并在其中将实现类通过@Bean注入,然后在spring.factories中配置该Configuration。
@Order(1) public class CustomizedPropertiesBinderAutoConfiguration { @Bean public CustomizedConfigurationPropertiesBinder customizedConfigurationPropertiesBinder() { return new CustomizedConfigurationPropertiesBinder(); } }