之前的一节说明了import的注册的几种方式,接下来来说最后一种注册方式:FactoryBean
我们需要实现FactoryBean,然后默认获取到的是工厂bean调用的getObject的对象。
1.我们先创建类MyBeanFactory来实现FactoryBean方法
package springanntition.beanFactory;
import org.springframework.beans.factory.FactoryBean;
import springorgin.demo.configbean.Color;
public class MyBeanFactory implements FactoryBean<Color> {
// 返回一个color对象,这个对象会添加到容器中
public Color getObject() throws Exception {
System.out.println("MyBeanFactory...getObject()。。。");
return new Color();
}
// 返回对象的类型
public Class<?> getObjectType() {
return Color.class;
}
// 是否是单例
// 返回true:这个bean是单实例的,在容器中就创建一份
// 返回false:是多实例的,每次获取都会创建一个新的bean,可以直接在里面改
public boolean isSingleton() {
return true;
}
}
创建color类
public class Color {
}
2.创建BeanTest类作为配置类用@Bean注入MyBeanFactory
package springanntition.beanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeanTest {
@Bean
public MyBeanFactory myBeanFactory() {
return new MyBeanFactory();
}
}
添加测试类
package springannotion.conditional;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import springanntition.beanFactory.BeanTest;
import springanntition.zjimport.ImportZJTest;
import springorgin.demo.configbean.RainBow;
public class ImportTest {
AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext(BeanTest.class);
@Test
public void iocTest() {
printBeans(applicationContext1);
//*****************************此为beanFactory测试***************************************
// 工厂bean获取的是调用Object创建对象
Object bean2 = applicationContext1.getBean("myBeanFactory");
Object bean3 = applicationContext1.getBean("myBeanFactory");
System.out.println("bean的类型:" + bean2.getClass());
System.out.println(bean2 == bean3);
//*****************************此为beanFactory测试结束************************************
}
private void printBeans(AnnotationConfigApplicationContext applicationContext) {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
运行,我们看到容器中注入了以下这些,myBeanFactory的想要注入的就是Color对象,也发现获取两次对象打印的都是true证明是单例。
我们修改看下怎么设置多实例的,在MyBeanFactory类里的isSingleton方法将return true改成return false
再运行一下,发现获取两次getObject方法,并且两个对象并不相等
测试类加上获取bean的id方式
public class ImportTest {
AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext(BeanTest.class);
@Test
public void iocTest() {
printBeans(applicationContext1);
//*****************************此为beanFactory测试***************************************
// 工厂bean获取的是调用Object创建对象
Object bean2 = applicationContext1.getBean("myBeanFactory");
Object bean3 = applicationContext1.getBean("myBeanFactory");
System.out.println("bean的类型:" + bean2.getClass());
System.out.println(bean2 == bean3);
// &就是获取容器中的id
Object bean4 = applicationContext1.getBean("&myBeanFactory");
System.out.println("bean4:" + bean4.getClass());
//*****************************此为beanFactory测试结束************************************
}
private void printBeans(AnnotationConfigApplicationContext applicationContext) {
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
System.out.println(name);
}
}
}
运行一下,发现获取的是MybeanFactory的全限定名
总结一下组件注册的几种方式
给容器中注册组件: 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component) 2)、@Bean[导入的第三方包里面的组件] 3)、@Import[快速给容器中导入一个组件], 1、@Import[要导入到容器中的组件],容器中就会自动注册到这个组件,id默认为类的全限定名。 2、ImportSelector:返回需要导入的组件的全类名数组 3、ImportBeanDefinitionRegistrar:手动注册bean到容器中 4)、使用spring提供的FactoryBean(工厂Bean) 1、默认获取到的是工厂bean调用getObject创建的对象 2、要获取到工厂Bean本身,我们需要给id前面加一个&标识