目录:1、@Import给容器快速导入一个组件 2、@Import使用importSelector注册组件 3、@Import使用importBeanDefinitionRegistrar注册组件 4、使用BeanFactory注册组件
回忆给容器中注入组件的方式:
1、包扫描+组件标注注解[@Controller @Service @Repository @Component]---自己写的类
2、@Bean--导入第三方包里面的组件--[在方法上method]
3、@Import----[在类上]
3.1)、@Import(要导入的组件),容器中就会自动注册这个组件,ID默认是全类名
3.2)、ImportSelector:[implements ImportSelector]返回需要导入的组件的全类名数组
3.3)、ImportBeanDefinitionRegistrar:[implements ImportBeanDefinitionRegistrar] 返回需要导入的组件的全类名数组
4、使用Spring提供的FactoryBean(工厂Bean)
4.1)、默认获取到的是工厂Bean调用getObject创建的对象
4.2)、要获取工厂bean本身,我们需要给ID钱面加一个&符
Color.class
package com.lee.bean;
public class Color {
}
Red.class
package com.lee.bean;
public class Red {
}
MainTest.class
@Test
public void testImport(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] names = context.getBeanDefinitionNames();
for(String name : names){
System.out.println("-->"+name);
}
}
结果:
-->mainConfig2
-->mainConfig
-->bookController
-->bookDao
-->bookService
-->person
-->bill
给MainConfig.class添加注解
@ComponentScan(value = "com.lee")//包扫描
@Configuration//这是个配置类
@Import({Color.class, Red.class})//给容器注册组件--id默认是全类名
public class MainConfig2 {
// @Lazy//懒加载
// @Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"张三","male");
}
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01(){
return new Person(2,"bill Gates","male");
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person02(){
return new Person(3,"linus","male");
}
}
结果:
-->mainConfig2
-->mainConfig
-->bookController
-->bookDao
-->bookService
-->person
-->com.lee.bean.Color
-->com.lee.bean.Red
-->bill
Blue.class
package com.lee.bean;
public class Blue {
}
Yellow.class
package com.lee.bean;
public class Yello {
}
MyImportSelector.class
package com.lee.conditions;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
/**
* 返回值,就是导入到容器中的组件的全类名
* AnnotationMetadata:当前标注@Import注解类的所有注解信息-MainConfig2
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.lee.bean.Blue","com.lee.bean.Yello"};
}
}
MainConfig2.class
package com.lee.config;
import com.lee.bean.Color;
import com.lee.bean.Person;
import com.lee.bean.Red;
import com.lee.conditions.LinuxCondition;
import com.lee.conditions.MyImportSelector;
import com.lee.conditions.WindowsCondition;
import org.springframework.context.annotation.*;
@ComponentScan(value = "com.lee")//包扫描
@Configuration//这是个配置类
@Import({Color.class, Red.class, MyImportSelector.class})//给容器注册组件--id默认是全类名
public class MainConfig2 {
// @Lazy//懒加载
// @Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"张三","male");
}
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01(){
return new Person(2,"bill Gates","male");
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person02(){
return new Person(3,"linus","male");
}
}
MainTest.class
@Test
public void testImportSelector(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] names = context.getBeanDefinitionNames();
for(String name : names){
System.out.println("-->"+name);
}
}
结果:
-->mainConfig2
-->mainConfig
-->bookController
-->bookDao
-->bookService
-->person
-->com.lee.bean.Color
-->com.lee.bean.Red
-->com.lee.bean.Blue
-->com.lee.bean.Yello
-->bill
RainBow.class
package com.lee.bean;
public class RainBow {
}
MyImportBeanDefinitionRegistrar.class
package com.lee.conditions;
import com.lee.bean.RainBow;
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;
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* AnnotationMetadata: 添加@Import类的所有注解信息
* BeanDefinitionRegistry:BeanDefinition注册类
* 把所有需要添加到容器中的bean:调用
* registry.registerBeanDefinition手工注册进来
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean isRed = registry.containsBeanDefinition("com.lee.bean.Red");//是否包含红色
boolean isBlue = registry.containsBeanDefinition("com.lee.bean.Blue");//是否包含蓝色
if(isRed && isBlue){
//指定 bean的信息,(bean的类型Rainbow.class)
RootBeanDefinition definition = new RootBeanDefinition(RainBow.class);
//注册一个bean,指定bean名
registry.registerBeanDefinition("rainBow",definition);
}
}
}
MainConfig2.class
package com.lee.config;
import com.lee.bean.Color;
import com.lee.bean.Person;
import com.lee.bean.Red;
import com.lee.conditions.LinuxCondition;
import com.lee.conditions.MyImportBeanDefinitionRegistrar;
import com.lee.conditions.MyImportSelector;
import com.lee.conditions.WindowsCondition;
import org.springframework.context.annotation.*;
@ComponentScan(value = "com.lee")//包扫描
@Configuration//这是个配置类
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})//给容器注册组件--id默认是全类名
public class MainConfig2 {
// @Lazy//懒加载
// @Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"张三","male");
}
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01(){
return new Person(2,"bill Gates","male");
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person02(){
return new Person(3,"linus","male");
}
}
结果:
-->mainConfig2
-->mainConfig
-->bookController
-->bookDao
-->bookService
-->person
-->com.lee.bean.Color
-->com.lee.bean.Red
-->com.lee.bean.Blue
-->com.lee.bean.Yello
-->bill
-->rainBow
ColorFactoryBean.class
package com.lee.bean;
import org.springframework.beans.factory.FactoryBean;
public class ColorFactoryBean implements FactoryBean<Color> {
//返回的类
@Override
public Color getObject() throws Exception {
return new Color();
}
//返回类的类型
@Override
public Class<?> getObjectType() {
return Color.class;
}
//是否单例
@Override
public boolean isSingleton() {
return true;
}
}
MainConfig2.class
package com.lee.config;
import com.lee.bean.Color;
import com.lee.bean.ColorFactoryBean;
import com.lee.bean.Person;
import com.lee.bean.Red;
import com.lee.conditions.LinuxCondition;
import com.lee.conditions.MyImportBeanDefinitionRegistrar;
import com.lee.conditions.MyImportSelector;
import com.lee.conditions.WindowsCondition;
import org.springframework.context.annotation.*;
@ComponentScan(value = "com.lee")//包扫描
@Configuration//这是个配置类
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})//给容器注册组件--id默认是全类名
public class MainConfig2 {
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
// @Lazy//懒加载
// @Scope(value = "prototype")
@Bean
public Person person(){
return new Person(1,"张三","male");
}
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01(){
return new Person(2,"bill Gates","male");
}
@Conditional(LinuxCondition.class)
@Bean("linus")
public Person person02(){
return new Person(3,"linus","male");
}
}
MainTest.class
@Test
public void testFactoryBean(){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig2.class);
String[] names = context.getBeanDefinitionNames();
for(String name : names){
System.out.println("-->"+name);
}
Object colorFactoryBean1 = context.getBean("colorFactoryBean");
System.out.println("bean的类型1:"+colorFactoryBean1.getClass());
Object colorFactoryBean2 = context.getBean("colorFactoryBean");
System.out.println(colorFactoryBean1 == colorFactoryBean2);
Object bean = context.getBean("&colorFactoryBean");
System.out.println("bean的类型2:"+bean.getClass());
}
结果:
-->mainConfig2
-->mainConfig
-->bookController
-->bookDao
-->bookService
-->person
-->com.lee.bean.Color
-->com.lee.bean.Red
-->com.lee.bean.Blue
-->com.lee.bean.Yello
-->colorFactoryBean
-->bill
-->rainBow
bean的类型1:class com.lee.bean.Color
true
bean的类型2:class com.lee.bean.ColorFactoryBean