往Spring容器中注册组件的方式

Posted 恒奇恒毅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了往Spring容器中注册组件的方式相关的知识,希望对你有一定的参考价值。

给容器中注册组件的方式

  1. 包扫描+标注注解(@Controller/@Service/@Repository/@Component)一般用于自己写的类
  2. @Configuration+@Bean,一般用于导入的第三方包里面的组件
  3. @Import,一般用于封装公共组件,提供jar包
/**
 * Indicates one or more @link Configuration @Configuration classes to import.
 *
 * <p>Provides functionality equivalent to the @code <import/> element in Spring XML.
 * Allows for importing @code @Configuration classes, @link ImportSelector and
 * @link ImportBeanDefinitionRegistrar implementations, as well as regular component
 * classes (as of 4.2; analogous to @link AnnotationConfigApplicationContext#register).
 *
 * <p>@code @Bean definitions declared in imported @code @Configuration classes should be
 * accessed by using @link org.springframework.beans.factory.annotation.Autowired @Autowired
 * injection. Either the bean itself can be autowired, or the configuration class instance
 * declaring the bean can be autowired. The latter approach allows for explicit, IDE-friendly
 * navigation between @code @Configuration class methods.
 *
 * <p>May be declared at the class level or as a meta-annotation.
 *
 * <p>If XML or other non-@code @Configuration bean definition resources need to be
 * imported, use the @link ImportResource @ImportResource annotation instead.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.0
 * @see Configuration
 * @see ImportSelector
 * @see ImportResource
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import 

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


  • @Import(组件);容器中就会自动注册这个组件,id默认是全类名,如果导入的是@Configuration,没那么其类中的@Bean也会全部被导入
  • @Import(ImportSelector或者DeferredImportSelector):返回需要导入的组件的全类名数组;
/**
 * Interface to be implemented by types that determine which @@link Configuration
 * class(es) should be imported based on a given selection criteria, usually one or more
 * annotation attributes.
 *
 * <p>An @link ImportSelector may implement any of the following
 * @link org.springframework.beans.factory.Aware Aware interfaces, and their respective
 * methods will be called prior to @link #selectImports:
 * <ul>
 * <li>@link org.springframework.context.EnvironmentAware EnvironmentAware</li>
 * <li>@link org.springframework.beans.factory.BeanFactoryAware BeanFactoryAware</li>
 * <li>@link org.springframework.beans.factory.BeanClassLoaderAware BeanClassLoaderAware</li>
 * <li>@link org.springframework.context.ResourceLoaderAware ResourceLoaderAware</li>
 * </ul>
 *
 * <p>ImportSelectors are usually processed in the same way as regular @code @Import
 * annotations, however, it is also possible to defer selection of imports until all
 * @code @Configuration classes have been processed (see @link DeferredImportSelector
 * for details).
 *
 * @author Chris Beams
 * @since 3.1
 * @see DeferredImportSelector
 * @see Import
 * @see ImportBeanDefinitionRegistrar
 * @see Configuration
 */
public interface ImportSelector 

	/**
	 * Select and return the names of which class(es) should be imported based on
	 * the @link AnnotationMetadata of the importing @@link Configuration class.
	 */
	String[] selectImports(AnnotationMetadata importingClassMetadata);


AnnotationMetadata可以获取到标注这个注解的类的相关信息,返回值不可为null,是导入类的全类名。
ImportSelector的实现类可以实现EnvironmentAwareBeanFactoryAwareBeanClassLoaderAwareResourceLoaderAware接口获取相关的环境信息。

  • @Import(BeanDefinitionRegistrar):手动注册bean到容器中
/**
 * Interface to be implemented by types that register additional bean definitions when
 * processing @@link Configuration classes. Useful when operating at the bean definition
 * level (as opposed to @code @Bean method/instance level) is desired or necessary.
 *
 * <p>Along with @code @Configuration and @link ImportSelector, classes of this type
 * may be provided to the @@link Import annotation (or may also be returned from an
 * @code ImportSelector).
 *
 * <p>An @link ImportBeanDefinitionRegistrar may implement any of the following
 * @link org.springframework.beans.factory.Aware Aware interfaces, and their respective
 * methods will be called prior to @link #registerBeanDefinitions:
 * <ul>
 * <li>@link org.springframework.context.EnvironmentAware EnvironmentAware</li>
 * <li>@link org.springframework.beans.factory.BeanFactoryAware BeanFactoryAware
 * <li>@link org.springframework.beans.factory.BeanClassLoaderAware BeanClassLoaderAware
 * <li>@link org.springframework.context.ResourceLoaderAware ResourceLoaderAware
 * </ul>
 *
 * <p>See implementations and associated unit tests for usage examples.
 *
 * @author Chris Beams
 * @since 3.1
 * @see Import
 * @see ImportSelector
 * @see Configuration
 */
public interface ImportBeanDefinitionRegistrar 

	/**
	 * Register bean definitions as necessary based on the given annotation metadata of
	 * the importing @code @Configuration class.
	 * <p>Note that @link BeanDefinitionRegistryPostProcessor types may <em>not</em> be
	 * registered here, due to lifecycle constraints related to @code @Configuration
	 * class processing.
	 * @param importingClassMetadata annotation metadata of the importing class
	 * @param registry current bean definition registry
	 */
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);


AnnotationMetadata可以获取到标注这个注解的类的相关信息,通过BeanDefinitionRegistry手动注册组件。
ImportBeanDefinitionRegistrar的实现类可以实现EnvironmentAwareBeanFactoryAwareBeanClassLoaderAwareResourceLoaderAware接口获取相关的环境信息。
5. 使用Spring提供的 FactoryBean,非常适合整合其他框架;
- 默认获取到的是工厂bean调用getObject创建的对象
- 要获取工厂Bean本身,我们需要给id前面加一个&
6. 直接注册一个Bean:SingletonBeanRegistry#registerSingleton

以上是关于往Spring容器中注册组件的方式的主要内容,如果未能解决你的问题,请参考以下文章

Spring——往容器中注册组件的方法总结

Spring @Configuration @Bean 给容器中注册组件

@Configuration和@bean给容器中注册组件

spring注解之组件注册

Spring Framework 组件注册 之 @Import

Spring源码解析