Spring之Bean的加载方法

@Configuration

该注解作用在类上,告诉Spring这是一个配置类,与XML效果是一样的,我们接下来所使用的注解,需要在配置类中使用。

ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfig.class);

@Bean

将@Bean放在方法上使用,能够将Bean加入到IOC容器中,其返回值代表Bean的类型,其方法名代表Bean的id。

@Bean
public Pig pig() {
    return new Pig();
}

@Scope扫描规则
在被标注为Bean的方法上可以使用@Scope,该注解的属性可以配置为

  • singleton:单实例(默认):IOC容器启动时会调用方法创建对象并放到IOC容器中,以后每次获取的就是直接从容器中拿出的同一个bean。
  • prototype:IOC容器启动时,IOC容器不会调用方法创建对象,而是每次获取的时候才会调用方法创建对象。
  • request:主要针对web应用,递交一次请求创建一个实例。
  • session:同一个session创建一个实例。

@lazy懒加载
在被标注为Bean的方法上可以使用@lazy,懒加载主要针对单实例,默认情况下,Bean在IOC容器启动时就被创建并加入到容器中,而使用懒加载,容器启动的时候不创建对象,当第一次使用Bean的时候才被创建。

@Conditional条件注册bean
@Condition可以按照一定条件进行判断,如果条件满足,那么就给容器注册bean
我们需要根据操作系统来判断是否注入bean,首先,我们创建一个WinCondition类,实现Spring为我们提供的Condition接口,实现其matches方法。

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
	//获取IOC容器中正在使用的BeanFactory
	BeanFactory factory = context.getBeanFactory();
	//获取当前环境变量
	Environment environment = context.getEnvironment();
	String os_name = environment.getProperty("os.name");
	if (os_name.contains("Windows")) {
		return true;
	}
	return false;
}

这样,我们就可以在配置类生成进行bean注入的方法上直接使用@Condition注解。

@Conditional(WinCondition.class)
@Bean
public Person zhangsan() {
	return new Person("zhangsan",22);
}

@ComponentScan扫描规则

指定扫描范围
其value属性用于指定包扫描范围

value= {"base.controller"}

扫描过滤器
includeFilters和excludeFilters属性可以对扫描进行过滤,其进行过滤的范围是value所指定的范围。
默认情况下,该注解的一个属性useDefaultFilters将会扫描指定包下被标注为@Component、@Controller、@Service、@Repository的类,如果设置useDefaultFilters=false,那么,默认扫描策略将会失效。
使用includeFilters将会在useDefaultFilters的基础上,继续添加你所需要的类
使用excludeFilters指定扫描到某个类时忽略它

@ComponentScan(value= {"cn.edu.pdsu.base.controller"},
            includeFilters= {
                @Filter(type=FilterType.ANNOTATION,classes= {Controller.class})
		},useDefaultFilters= false)

自定义过滤规则
通过配置@Filter,我们也可以自定义过滤规则

@Filter(type=FilterType.CUSTOM,classes= {MyTypeFilter.class}

我们创建类MyTypeFilter.java,实现TypeFilter接口。

/**
 * @param metadataReader:读取到当前正在扫描类的信息
 * @param metadataReaderFactory:可以获取其他任何类的信息
 */
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
		throws IOException {
	//获取当前类注解的信息
	AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
	//获取当前类资源(类路径)
	Resource resource = metadataReader.getResource();
	
   //获取当前正在扫描的类信息
	ClassMetadata classMetadata = metadataReader.getClassMetadata();
	String className = classMetadata.getClassName();
	System.out.println("----->"+className);
	
	if (className.contains("User")) {//在指定包下扫描到包含User的类,也会被实例化为bean		return true;
	}
	return false;
}

@Import注册bean

通过@Import,容器会自动注册这个组件,bean的id为全限定类名

@Import(value = {Dog.class})

我们也可以通过实现ImportSelector接口,返回需要导入到容器的组件的全类名数组,来完成bean的注册。

public class PigImportSelector implements ImportSelector {
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            //传入全限定类名
		return new String[] {"cn.edu.pdsu.base.pojo.Pig"};
	}
}
@Import(value = {PigImportSelector.class})

通过实现ImportBeanDefinitionRegistrar,使用BeanDefinitionRegistry将bean注册到IOC容器中。

public class PigImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		RootBeanDefinition beanDefinition = new RootBeanDefinition(Pig.class);
		registry.registerBeanDefinition("pig", beanDefinition);
	}
}
@Import(value = {PigImportBeanDefinitionRegistrar.class})

FactoryBean

通过Spring提供的FactoryBean接口,我们也可以实现bean的注册。
创建PigFactoryBean,实现FactoryBean接口

public class PigFactoryBean implements FactoryBean<Pig> {
	public Pig getObject() throws Exception {
		return new Pig();
	}
	public Class<?> getObjectType() {
		return Pig.class;
	}
	public boolean isSingleton() {
		return true;
	}
}

在配置类中引入当前bean

@Bean
public PigFactoryBean pig() {
	return new PigFactoryBean();
}

我们在测试中查看其类型

Object bean = ac.getBean("pig");
System.out.println(bean.getClass());//base.pojo.Pig

我们可以看到,我们已经把Pig类加载到容器中去了

Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,工厂Bean跟普通Bean不同,它所返回的对象不是指定类的一个实例,而是该工厂Bean的getObject方法所返回的对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值