前言
在平常利用SpringBoot开发的过程当中,咱们开发的Bean大部分都是依赖于spring容器进行管理,这样很方便平常Bean的注入。
你们都知道对象的建立必须经过构造方法建立,构造方法分为两种,一种时无参(此方法只是建立了个空对象,后续使用属性时还须要set/get),另一种时重载的有参构造器(此方法建立后的对象,对于已经赋值的属性固然能够立马使用),因此Spring在建立Bean的时候也无非就这两种(默认时无参构造建立),基于spring体系的疮痈建立Bean注解有:好比@Configuration里的@Bean,好比@Component,若是是spring mvc的话,还有一些专用的@Controller,@Service,@Repository。java
引入
那么,使用spring boot时,若是想本身实现一些初始设置比较复杂的bean时,能够在类上用@Configuration注解,而后类内部在返回具体bean的方法上使用@Bean注解。
那么,要让容器找到这个配置类,并让容器进行管理的话,方法有这么几种:spring
方法一:@ComponentScan注解
将配置类放到@ComponentScan注解所指定的package里。
如下是截取springboot Guide中的一段话:sql
方法二:使用@Import注解
首先,@Import是spring中的内置注解,因此spring会对此注解进行管理。 这个注解的主要用途截取spring的源码说明,而后逐一讲解:
a.容许使用@Configuration注解的类
这个比较简单,若是明确知道须要引入哪一个配置类,直接引入就能够。springboot
b.容许是实现ImportSelector接口的类
若是并不肯定引入哪一个配置类,须要根据@Import注解所标识的类或者另外一个注解(一般是注解)里的定义信息选择配置类的话,用这种方式。
比较典型的是注解@EnableTransactionManagementmybatis
java代码: @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({TransactionManagementConfigurationSelector.class}) public @interface EnableTransactionManagement { boolean proxyTargetClass() default false; AdviceMode mode() default AdviceMode.PROXY; int order() default 2147483647; }
是经过TransactionManagementConfigurationSelector类,根据注解@EnableTransactionManagement所指定的AdviceMode来选择使用哪一个配置类的。mvc
java代码: public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> { @Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME}; default: return null; } } }
c.容许是实现了ImportBeanDefinitionRegistrar接口的类
通常只要用户确切的知道哪些bean须要放入容器的话,本身即可以经过spring boot里所提供的注解来标识了,好比@Configuration里的@Bean,好比@Component,若是是spring mvc的话,还有一些专用的@Controller,@Service,@Repository。
可是,若是是第三方包,并且又不是肯定的类,而且这些类并非spring专用,因此不想用spring的注解进行侵入式标识,那么若是找到这些类放到spring的容器呢?
这时候就用到了用注解@Import引入ImportBeanDefinitionRegistrar子类的方式,最典型的应用就是mybatis,使用工具自动生成了一批mapper和entity,而如何把这些普通的类放入容器,就是经过注解app
典型表明@MapperScanide
java代码: @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
public @interface MapperScan {
String[] value() default {};
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends Annotation> annotationClass() default Annotation.class;
Class<?> markerInterface() default Class.class;
String sqlSessionTemplateRef() default "";
String sqlSessionFactoryRef() default "";
Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;
}工具
这个注解用@Import引入了MapperScannerRegistrar类,这个类里会取得注解@MapperScan做设置的package,而后扫描这个package下全部的类,并放入容器中。ui
d.正如源码中的备注同样,"as well as regular component",说明,Import能够像相似于@Component此功能的注解同样,在容器启动的时候将此类定义为一个bean,并将此bean交于容器管理,但此用法较少。