一、组件说明
@Conditional({xxx.class, xxx.class}),可用在方法和类上面
按照一定的条件进行判断,把满足条件的bean注册到springIOC容器中。
@Import({xxx.class}) 用在类上面,要导入springIOC容器中的组件,也就是bean,容器会自动注册这个组件,id默认是全类名,实现方式有三种。
1.直接用类
@Configuration
@ComponentScan(basePackages = {"com.guang"})
@Import(value = {Dog.class, Horse.class})
public class Myconfig {}
2. ImportSelector接口的实现类:@Import的值,也可以是实现了ImportSelector接口的实现类,这个实现类是我们自己定义的需要加入到springioc容器中的bean。实现如下:
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* 自定义需要返回的加入到容器中的组件
*
* @ClassName ImportSelectorCustom
* @author xxx
* @date xxx
* @version xxx
*/
public class ImportSelectorCustom implements ImportSelector {
/**
* 这个方法不能返回 null 否则会报错,程序不能往下走
*
* @Title: selectImports
* @param importingClassMetadata 当前标@Import类的注解的所有的信息
* @return 返回自己定义注册组件bean的所有的bean
* @see org.springframework.context.annotation.ImportSelector#selectImports(org.springframework.core.type.AnnotationMetadata)
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[] {"com.guang.animal.Fish", "com.guang.animal.Goose"};
}
}
此时@Import可以如下写
@Configuration
@ComponentScan(basePackages = {"com.guang"})
@Import(value = {Dog.class, Horse.class, ImportSelectorCustom.class})
public class Myconfig {}
3.ImportBeanDefinitionRegistrar接口的实现类:@Import的值,也可以是实现了ImportBeanDefinitionRegistrar接口的实现类,这个实现类是我们指定加入的实现类,实现过程是先判断有没有这个指定的bean,如果有则创建这个bean,并且可以指定这个bean的名字。实现如下:
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import com.guang.animal.Pig;
/**
* 自己手工加入指定的bean
*
* @ClassName ImportBeanDefinitionRegistrarCustom
* @author xxx
* @date xxx
* @version xxx
*/
public class ImportBeanDefinitionRegistrarCustom implements ImportBeanDefinitionRegistrar {
/**
*
* @Title: registerBeanDefinitions
* @Description: 覆盖方法注释标签说明
* @param importingClassMetadata 带有@Import这个类的所有的注解信息
* @param registry
* BeanDefinition注册类,这个类的意思是把所有需要手工加入的bean通过BeanDefinitionRegistry.registerBeanDefinition注册进来
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata,
* org.springframework.beans.factory.support.BeanDefinitionRegistry)
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
boolean beanDefinition = registry.containsBeanDefinition("com.guang.animal.Pig");
if (beanDefinition) {
// 指定Bean定义信息(Bean的类型),为这个定义的bean指定名称
registry.registerBeanDefinition("pipi", new RootBeanDefinition(Pig.class));
}
}
}
调用如下:
@Configuration
@ComponentScan(basePackages = {"com.guang"})
@Import(value = {Dog.class, Horse.class, ImportSelectorCustom.class,
ImportBeanDefinitionRegistrarCustom.class})
public class Myconfig {}
4.使用Spring提供的 FactoryBean(工厂Bean);
import org.springframework.beans.factory.FactoryBean;
import com.guang.animal.Horse;
/**
* 使用SpringFactory为IOC容器添加bean
*
* @ClassName HorseFactory
* @author xxx
* @date xxx
* @version xxx
*/
public class HorseFactory implements FactoryBean {
/**
* 返回一个bean,这个bean会添加到IOC容器中
*
* @Title: getObject
* @Description: 覆盖方法注释标签说明
* @return
* @throws Exception
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
@Override
public Horse getObject() throws Exception {
return new Horse();
}
/**
*
* @Title: getObjectType
* @Description: 覆盖方法注释标签说明
* @return
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
*/
@Override
public Class getObjectType() {
return Horse.class;
}
/**
* 使用factoryBean注册的bean是不是单例的,true返回单例,false代表多例
*
* @Title: isSingleton
* @Description: 覆盖方法注释标签说明
* @return
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
*/
@Override
public boolean isSingleton() {
return false;
}
}
使用
/**
* 使用SpringFactory为IOC容器添加bean
*/
@Bean
public HorseFactory horseFactoryBean() {
return new HorseFactory();
}
综上:
给容器中注册组件;
1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
2)、@Bean[导入的第三方包里面的组件]
3)、@Import[快速给容器中导入一个组件]
1)、@Import
2)、ImportSelector
3)、ImportBeanDefinitionRegistrar
4)、使用Spring提供的 FactoryBean(工厂Bean);
1)、默认获取到的是工厂bean调用getObject创建的对象
2)、要获取工厂Bean本身,我们需要给id前面加一个&,例如:&colorFactoryBean