spring注解驱动开发(三):容器注册组件的四种方式
将自定义的bean注册到容器中可以有一下集中方式,第一使用org.springframework.stereotype下的相关注解;第二只用@Bean第三使用@Import;第四类实现FactoryBean接口。
一:自己写的类用@Controller\@Service\@Repository\@Component,结合包扫描
二:使用@Bean注解,将外部类以new的方式注入
三:使用@Import注解
①@Import(Xxx.class)直接向容器注册类
②实现ImportSelector 接口,自定义将全类名以数据的方式返回
③实现ImportBeanDefinitionRegistrar接口,通过registerBeanDefinitions手工来注册bean
四:使用实现FactoryBean接口,getObject方法来注册bean
1 使用Context下org.springframework.stereotype包注解,结合包扫描

使用@Component、@Controller、@Service、@Repository注解,将所修饰的类注册到spring容器中。
不是自己写的类,没有加这四种注解,不能注入。该中方式适合自定义的类。
2 使用Context下org.springframework.context.annotation包注解

使用@Bean注解,将外部定义的类以new的方式注入到容器中。
可以将自定义类,外部类以new的方式添加进容器。
3 使用Import注册组件
3.1 在配置类中使用@Important
@Configuration @Import(Color.class) public class MainConfigImport02 { }
控制台打印容器中的组件
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigImport02
org.gwsix.ch02.bean.Color
在控制台中输出org.gwsix.ch02.bean.Color,说明color注册到容器中,bean的名字默认是【包名+类名】。
3.2 实现ImportSelector接口,将对应的类注册到bean
自定义返回值作为组件名导入到容器中。
1.自定义类实现ImportSelect接口,方法的返回值是要注入到bean的全类名,如果路径不存在,会抛出异常,异常类型是--》org.springframework.beans.factory.BeanDefinitionStoreException:
public class MyImportSelector implements ImportSelector { /** * importingClassMetadata 当前标注@Import中类中所有bean信息 * @param importingClassMetadata * @return */ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"org.gwsix.ch02.bean.Red","org.gwsix.ch02.bean.Yellow"}; } }
2.在配置类直接导入这个类
@Configuration @Import({Color.class, MyImportSelector.class}) public class MainConfigImport02 { }
3.启动测试类,打印容器中所有bean的名字,在控制台输出会看到Red和Yellow被注入到容器中,容器中对应bean的名字org.gwsix.ch02.bean.Red和org.gwsix.ch02.bean.Yellow
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigImport02
org.gwsix.ch02.bean.Color
org.gwsix.ch02.bean.Red
org.gwsix.ch02.bean.Yellow
注意:MyImportSelector并没有被导入到容器中,导入容器的仅仅是selectImports返回值。
3.3 实现ImportBeanDefinitionRegistrar接口,自定义注册bean
1.自定义类实现ImportBeanDefinitionRegistrar接口
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { /** * importingClassMetadata:当前类的注解信息和其他信息 * registry:可以调用相关方法将bean注册和移除bean * @param importingClassMetadata * @param registry */ @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { if(registry.containsBeanDefinition("org.gwsix.ch02.bean.Yellow")){ //指定bean名 BeanDefinition beanDefinition = new RootBeanDefinition(Blue.class); registry.registerBeanDefinition("blue",beanDefinition); } } }
2.将自定义MyBeanDefinitionRegistrar导入到配置文件
@Configuration @Import({Color.class, MyImportSelector.class, MyBeanDefinitionRegistrar.class}) public class MainConfigImport02 { }
3.启动测试类,打印容器中的bean,发现blue注入到容器中
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfigImport02
org.gwsix.ch02.bean.Color
org.gwsix.ch02.bean.Red
org.gwsix.ch02.bean.Yellow
blue
注意:BeanDefinition beanDefinition = new RootBeanDefinition(Blue.class); 指定注入类的类名
使用@Import注解可以将【单个类的class直接导入】、【可以在外部自定义类实现ImportSelector接口,selectImports中方法的返回值】、【自定义实现ImportBeanDefinitionRegistrar接口,通过RootBeanDefinition(Blue.class); 指定注入类的类名】
4 使用spring的工厂bean(FactoryBean)
1.自定义工厂bean实现FactoryBean接口
public class MyFactoryBean implements FactoryBean<Color> { //注入的bean @Override public Color getObject() throws Exception { return new Color(); } //类型 @Override public Class<?> getObjectType() { return Color.class; } //是否单例 @Override public boolean isSingleton() { return true; } }
2.在配置类使用@Bean将新建的工厂类注入到容器中
@Configuration public class MainConfigFactory02 { @Bean public MyFactoryBean myFactoryBean(){ return new MyFactoryBean(); } }
3.在测试类中添加方法测试bean是否注入到bean
//System.out.println(applicationContext.getBean("&myFactoryBean").getClass()); //获得工厂bean @Test public void testFactory(){ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigFactory02.class); printBeanName(applicationContext); //默认是获得工厂bean创建的对象 System.out.println(applicationContext.getBean("myFactoryBean").getClass()); //获得工厂Bean本身,需要在bean名前加入“&” //String FACTORY_BEAN_PREFIX = "&"; System.out.println(applicationContext.getBean("&myFactoryBean").getClass()); }
控制台输出以下内容
org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory mainConfigFactory02 myFactoryBean class org.gwsix.ch02.bean.Color class org.gwsix.ch02.bean.MyFactoryBean
可以发现使用&beanName可以打印出工厂类,在BeanFactory接口中的FACTORY_BEAN_PREFIX定义&BeanName可以获得工厂bean的
以上四种方法,均可以将bean注册到容器中,
第一种:需要配置包扫描
第二种:@Bean
第三种:@Import
第四种:实现BeanFactory

浙公网安备 33010602011771号