Spring组件注册

@Bean注解是给容器中注册一个Bean,类型是返回值的类型,id默认是方法名作为id

@Bean("person")
public Person person2(){
    System.out.println("create a new bean of person");
    return new Person();
}

@ComponentScan
@ComponentScan(value = “com.eric”,excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})

@ComponentScan 的属性

value:指定要扫描的包
excludeFilters = Filter[]:指定扫描的时候按照什么规则排除哪些组件
includeFilters = Filter[]:指定扫描的时候只需要包含哪些组件
/**

  • Description: spring-parent

  • 配置类==配置文件

  • @author caoqianqian

  • @date 2021/2/14
    */
    @Configuration //告诉Spring这是一个配置类
    @ComponentScan(value = “com.eric”,excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class, Service.class})
    })
    public class MainConfig {

    //给容器中注册一个Bean,类型是返回值的类型,id默认是方法名作为id
    @Bean
    public Person person(){
    return new Person(“testName”,20);
    }
    }
    @Scope
    通过@Scope注解来制定该bean的作用范围,也可以说是调整作用域,ioc容器中加载的组件默认是单实例的。

作用域范围即value的可取值范围

prototype 多实例的:ioc容器启动并不会去调用方法创建对象放到容器中,每次获取的时候才会调用方法创建对象。
singleton 单实例的(默认值):
ioc容器启动时会调用方法创建对象,放到ioc容器中,以后每次获取就是从容器中(map.get())拿
request 同一次请求创建一个实例
session 同一个session创建一个实例
//通过@Scope注解来制定该bean的作用范围,也可以说是调整作用域
@Scope(“singleton”)
@Bean(“person”)
public Person person() {
System.out.println(“I’m creating an instance Person”);
return new Person(“Person”, 28);
}
@Lazy 懒加载
单实例bean:默认在容器启动的时候创建对象。
懒加载:容器启动不创建对象,第一次使用(获取)bean时创建对象,并初始化。

单实例bean加上懒加载的注解之后容器启动时不创建对象,第一次使用时才会去创建对象并初始化。

@Bean("person")
@Lazy
public Person person2(){
    System.out.println("create a new bean of person");
    return new Person();
}

@Conditional
@Conditional按照一定的条件进行判断,满足条件给容器中注册bean

标在方法上,表示这个方法满足一定条件才会生效。

标在类上,类中组件统一设置,表示满足当前条件,这个类中配置的所有bean注册才会生效

判断是否是Linux系统

public class LinuxCondition implements Condition {
/**
*判断是否是Linux系统
* @param conditionContext 判断条件能使用的上下文(环境)
* @param annotatedTypeMetadata 当前标注注解的注释信息
* @return
*/
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//能获取到ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();

	//判断容器中bean的注册情况
	boolean definition = registry.containsBeanDefinition("person");
	RootBeanDefinition beanDefinition = new RootBeanDefinition(Person.class);
	//给容器中注册bean
	registry.registerBeanDefinition("person2",beanDefinition);
	String property = environment.getProperty("os.name");

	if(property.contains("linux")){
		return true;
	}
	return false;
}

}
判断是否是Windows系统

public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String osName = environment.getProperty(“os.name”);
if (osName.contains(“Windows”)){
return true;
}
return false;
}
}
配置类

@Configuration
public class MainConfig2 {
/**
*Conditional({Condition}):按照一定的条件进行判断,满足条件给容器中注册bean
* 如果系统是windows,给容器中注册(“bill”)
* 如果系统是linux,给容器中注册(“linus”)
* @return
*/
@Conditional({WindowsCondition.class})
@Bean(“bill”)
public Person person(){
return new Person(“Bill Gates”,62);
}

@Conditional({LinuxCondition.class})
@Bean("linus")
public Person person2(){
    return new Person("linus",42);
}

@Bean
public ColorFactoryBean colorFactoryBean(){
    return new ColorFactoryBean();
}

}
测试方法

    @Test
public void testCondition() {
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class);
	ConfigurableEnvironment environment = ac.getEnvironment();
	String[] beanNamesForType = ac.getBeanNamesForType(Person.class);
	//动态获取环境变量的值:windows 7
	String property = environment.getProperty("os.name");
	System.out.println(property);
	for (String p:beanNamesForType) {
		System.out.println(p);
	}
}

运行结果如下,Windows 7的系统所以bill注册了进来

Windows 7
bill
person2
@Import
快速导入组件,id默认是组件的全类名

配置类上加了@Import注解

@Configuration
@Import({Color.class, Dog.class})
public class MainConfig2 {
/**
*Conditional({Condition}):按照一定的条件进行判断,满足条件给容器中注册bean
* 如果系统是windows,给容器中注册(“bill”)
* 如果系统是linux,给容器中注册(“linus”)
* @return
*/
@Conditional({WindowsCondition.class})
@Bean(“bill”)
public Person person(){
return new Person(“Bill Gates”,62);
}

@Conditional({LinuxCondition.class})
@Bean("linus")
public Person person2(){
    return new Person("linus",22);
}

}
测试方法

    @Test
public void testImport() {
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class);
	String[] beanNamesForType = ac.getBeanDefinitionNames();
	for (String p:beanNamesForType) {
		System.out.println(p);
	}
}

运行结果:除了内部的bean,Color和Dog也被注册进来了

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.eric.bean.Color
com.eric.bean.Dog
bill
person2
@Import使用ImportSelector
//自定义逻辑返回需要导入的组件
public class MyImportSelector implements ImportSelector {
//返回值就是导入到容器中的组件的全类名
//AnnotationMetadata 当前标注@Import注解类的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
Set annotationTypes = annotationMetadata.getAnnotationTypes();
for(String str : annotationTypes){
System.out.println("===="+str);
}

    return new String[]{"com.eric.bean.Blue","com.eric.bean.Red"};
}

}
@Import注解加上自定义的组件MyImportSelector

@Configuration
@Import({Color.class, Dog.class,MyImportSelector.class})
public class MainConfig2 {
/**
*Conditional({Condition}):按照一定的条件进行判断,满足条件给容器中注册bean
* 如果系统是windows,给容器中注册(“bill”)
* 如果系统是linux,给容器中注册(“linus”)
* @return
*/
@Conditional({WindowsCondition.class})
@Bean(“bill”)
public Person person(){
return new Person(“Bill Gates”,62);
}

@Conditional({LinuxCondition.class})
@Bean("linus")
public Person person2(){
    return new Person("linus",22);
}

}
测试方法

    @Test
public void testImport() {
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class);
	String[] beanNamesForType = ac.getBeanDefinitionNames();
	for (String p:beanNamesForType) {
		System.out.println(p);
	}
}

运行结果:Blue Red 都被注册进来了

====org.springframework.context.annotation.Configuration
====org.springframework.context.annotation.Import
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
mainConfig2
com.eric.bean.Color
com.eric.bean.Dog
com.eric.bean.Blue
com.eric.bean.Red
bill
person2
@Import使用ImportBeanDefinitionRegistrar
手动注册bean到容器中

//要被注册的bean
public class Rainbow {
}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

/**
 *
 * @param importingClassMetadata    当前类的注解信息
 * @param registry                  BeanDefinition注册类
 *        把所有需要添加到容器中的bean,调用
 *        BeanDefinitionRegistry.registerBeanDefinition手工注册进来
 */
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    boolean blueDefinition = registry.containsBeanDefinition("com.eric.bean.Blue");
    if (blueDefinition){
        //指定bean的定义信息
        RootBeanDefinition beanDefinition = new RootBeanDefinition(Rainbow.class);
        //注册一个bean,指定bean名
        registry.registerBeanDefinition("rainbow", beanDefinition);
    }
}

}
配置类:@Import加入了中MyImportBeanDefinitionRegistrar

@Configuration
@Import({Color.class, Blue.class,MyImportBeanDefinitionRegistrar.class})
public class MainConfig2 {

}
测试方法:

    @Test
public void testImport() {
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class);
	String[] beanNamesForType = ac.getBeanDefinitionNames();
	for (String p:beanNamesForType) {
		System.out.println(p);
	}
}

运行结果:逻辑判断Blue存在所以rainbow被注册了进来

mainConfig2
com.eric.bean.Blue
bill
person2
rainbow
使用FactoryBean注册组件
使用spring提供的FactoryBean(工厂Bean)

创建一个ColorFactoryBean实现FactoryBean接口:

//创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean {

/**
 * 返回一个Color对象,这个对象会添加到容器中
 * @return
 * @throws Exception
 */
@Override
public Color getObject() throws Exception {
    System.out.println("ColorFactoryBean=========getObject=====");
    return new Color();
}

/**
 * 返回的bean类型
 * @return
 */
@Override
public Class<Color> getObjectType() {
    return Color.class;
}

/**
 * 是否单例
 * 返回true代表是单实例,在容器中保存一份
 * false是多实例,每次获取都会创建一个新的bean
 * @return
 */
@Override
public boolean isSingleton() {
    return true;
}

}
配置类里注册该工厂bean

@Configuration
public class MainConfig2 {

@Bean
public ColorFactoryBean colorFactoryBean(){
    return new ColorFactoryBean();
}

}
测试方法:

    @Test
public void testFactoryBean() {
	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig2.class);
	//工厂bean获取的是调用getObject()方法创建的对象
	Object bean1 = ac.getBean("colorFactoryBean");
	Object bean2 = ac.getBean("colorFactoryBean");

	System.out.println("bean的类型:"+bean1.getClass());
	//单实例返回true  多实例返回false
	System.out.println(bean1 == bean2);

	//默认获取到的是工厂bean调用getObejct创建的对象
	//要获取工厂bean本身,我们需要给id前面加一个&标识
	Object bean3 = ac.getBean("&colorFactoryBean");
	System.out.println("bean3的类型:"+bean3.getClass());

}

运行结果: 单实例获取到的是相同的bean,加&之后获取到的bean为ColorFactoryBean

ColorFactoryBean=====getObject=
bean的类型:class com.eric.bean.Color
true
bean3的类型:class com.eric.condition.ColorFactoryBean

USB Microphone https://www.soft-voice.com/
Wooden Speakers https://www.zeshuiplatform.com/
亚马逊测评 www.yisuping.cn
深圳网站建设www.sz886.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值