目录
1、@Import(要导入容器中的组件)方式,容器中就会自动注册这个组件,id默认为组件全类名。
2、@ImportSelector方式:返回需要导入的组件的全类名数组
3、@ImportBeanDefinitionRegistrar方式:手工注册bean到容器中。
4、使用Spring提供的FactoryBean(工厂Bean)
- 包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)【局限于自己创建的类】 前面已经讲解
- @Bean【导入的第三方包里面的组件】 前面已经讲解
- @Import【快速给容器中导入一个第三方组件】
-@Import(要导入容器中的组件)方式,容器中就会自动注册这个组件,id默认为组件全类名。
-@ImportSelector方式:返回需要导入的组件的全类名数组
-@ImportBeanDefinitionRegistrar方式:手工注册bean到容器中
- 使用Spring提供的FactoryBean(工厂Bean)
今天我们说下@Import方式
1、@Import(要导入容器中的组件)方式,容器中就会自动注册这个组件,id默认为组件全类名。
为了测试方便,我们自己创建类Color 和 Red类,通过import 导入进来。
package com.spring.bean;
public class Color {
}
package com.spring.bean;
public class Red {
}
配置类中引入组件
@Configuration
@Import({Color.class, Red.class})
public class MainConfig2 {
}
测试方法:
public class IocTest {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void test04(){
printBeans();
}
private void printBeans(){
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for(String name:beanDefinitionNames){
System.out.println(name);
}
}
}
输出结果:
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
mainConfig2
com.spring.bean.Color
com.spring.bean.Red
2、@ImportSelector方式:返回需要导入的组件的全类名数组
创建两个类,通过这种方式引入
package com.spring.bean;
public class Book {
}
package com.spring.bean;
public class User {
}
创建自定义Selector,实现ImportSelector接口,返回值中加入User、Book的全类名
package com.spring.Condition;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {
/**
* 返回值,就是导入到容器中的组件的全类名
* @param importingClassMetadata 当前标注@Import注解的类的所有注解信息
* @return
*/
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.spring.bean.User","com.spring.bean.Book"};
}
}
配置类中@Import MyImportSelector
@Configuration
@Import({Color.class, Red.class, MyImportSelector.class})
public class MainConfig2 {
}
测试输出容器中的组件
public class IocTest {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void test04(){
printBeans();
}
private void printBeans(){
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for(String name:beanDefinitionNames){
System.out.println(name);
}
}
}
结果为:
三月 29, 2020 12:28:40 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@37d31475: startup date [Sun Mar 29 00:28:40 CST 2020]; root of context hierarchy
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
mainConfig2
com.spring.bean.Color
com.spring.bean.Red
com.spring.bean.User
com.spring.bean.Book
3、@ImportBeanDefinitionRegistrar方式:手工注册bean到容器中。
创建类Car,通过这种方式方式引入(测试方便,未引入第三方组件)
package com.spring.bean;
public class Car {
}
创建接口ImportBeanDefinitionRegistrar 的实现类 MyImportBeanDefinitionRegistrar
package com.spring.Condition;
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 {
/**
*
* @param importingClassMetadata 当前类的注解信息
* @param registry :BeanDefinition注册类
* 把需要添加到容器中的bean,BeanDefinitionRegistry.registerBeanDefinition 手工注册。
*/
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean b = registry.containsBeanDefinition("com.spring.bean.Book");
boolean b1 = registry.containsBeanDefinition("com.spring.bean.User");
//如果容器中有 Book 和User组件,就将 Car组件注册到容器中
if(b && b1){
registry.registerBeanDefinition("car",new RootBeanDefinition("com.spring.bean.Car"));
}
}
}
配置类中@Import(MyImportBeanDefinitionRegistrar.class)
@Configuration
@Import({Color.class, Red.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {
}
执行打印输出容器中的组件,结果为
三月 29, 2020 12:46:37 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@37d31475: startup date [Sun Mar 29 00:46:37 CST 2020]; root of context hierarchy
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
mainConfig2
com.spring.bean.Color
com.spring.bean.Red
com.spring.bean.User
com.spring.bean.Book
car
car 对象已经注册入ioc容器中!
4、使用Spring提供的FactoryBean(工厂Bean)
首先实现FactoryBean 接口
package com.spring.bean;
import org.springframework.beans.factory.FactoryBean;
//创建一个Spring 定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {
//返回Color对象,这个对象会添加容器中
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean...getObject....");
return new Color();
}
public Class<?> getObjectType() {
return Color.class;
}
/**
* 是否单实例
* true 单实例,在容器中存在一份
* false 多实例,每次获取都会创建一个新bean
* @return
*/
public boolean isSingleton() {
return true;
}
}
package com.spring.bean;
public class Color {
}
在配置类中加入方法,通过工厂类获取实例。
@Configuration
public class MainConfig2 {
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
}
测试一下,看容器中注册了什么对象实例
@Test
public void testImport(){
printBeans();
//工厂Bean 获取的是调用getObject创建的对象
Object colorFactoryBean = annotationConfigApplicationContext.getBean("colorFactoryBean");
Object colorFactoryBean2 = annotationConfigApplicationContext.getBean("colorFactoryBean");
System.out.println("bean 类型:"+colorFactoryBean.getClass());
System.out.println(colorFactoryBean==colorFactoryBean2);
}
private void printBeans(){
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for(String name:beanDefinitionNames){
System.out.println(name);
}
}
结果返回:
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@37d31475: startup date [Sun Mar 29 08:20:03 CST 2020]; root of context hierarchy
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
mainConfig2
colorFactoryBean
ColorFactoryBean...getObject....
bean 类型:class com.spring.bean.Color
true
可以看出注册组件id 为:colorFactoryBean 类型却是:com.spring.bean.Color
并且两次创建是同一实例(单例)
如果改变方法:isSingleton() 的返回值为false
public boolean isSingleton() {
return false;
}
结果可以看出创建两个不同对象实例,创建了两次。
ColorFactoryBean...getObject....
ColorFactoryBean...getObject....
bean 类型:class com.spring.bean.Color
false
如果需要获取工厂bean本身,只需要id前加入&符号
Object colorFactoryBean3 = annotationConfigApplicationContext.getBean("&colorFactoryBean");
System.out.println(colorFactoryBean3.getClass());
返回结果为
class com.spring.bean.ColorFactoryBean