因为最近在研究学习spring boot,所以这里想详细学习回顾了一下spring 容器对bean的一些管理方式和部分源码学习。
首先初始类AnnotationConfigApplicationContext,简单源码查看,支持两个参数一个为扫描,一个为传递配置类,这里我们使用的第一个
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
public AnnotationConfigApplicationContext(String... basePackages) {
this();
this.scan(basePackages);
this.refresh();
}
下面在上面的基础上进行扩展学习,首先看一下要分析的源码
public Object getBean(String name) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(name);
}
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(name, requiredType);
}
public Object getBean(String name, Object... args) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(name, args);
}
public <T> T getBean(Class<T> requiredType) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(requiredType);
}
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
this.assertBeanFactoryActive();
return this.getBeanFactory().getBean(requiredType, args);
}
这里只测试其中的几种,有兴趣的可以自己测试其余部分
方式一:根据类获取bean对象
public class BeandemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
//方式一
System.out.println(context.getBean(DemoBean.class ));
context.close();
}
}
@Configuration
public class DemoConfig {
@Bean
public DemoBean createDemoBean(){
//注意默认 bean名称为方法名称,createDemoBean ,默认scope为单例模式,这个可以多次获取bean比较
// @Bean(name="") 指定名字 @Scope("prototype") 非单例模式
return new DemoBean();
}
}
public class DemoBean {
}
方式二:根据bean名称,这里需要注意一下默认bean名称,和如何自定义bena名称
方法三:通过Factorybean实现
public class DemoFactoryBean implements FactoryBean<DemoBean2> {
//获取bean对象
public DemoBean2 getObject() throws Exception {
return new DemoBean2();
}
//对象的类型
public Class<?> getObjectType() {
return DemoBean2.class;
}
//是否单例
public boolean isSingleton() {
return false;
}
}
@Configuration
public class DemoConfig {
@Bean
@Scope("prototype")
public DemoBean createDemoBean(){
return new DemoBean();
}
@Bean(name="factoryBean")
public RunnableFactoryBean getFactoryBean(){
return new RunnableFactoryBean();
}
}
public class BeandemoApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DemoConfig.class);
//方式一
System.out.println(context.getBean(DemoBean.class ));
System.out.println(context.getBean("createDemoBean"));
System.out.println(context.getBean("factoryBean"));
System.out.println(context.getBean(DemoBean2.class));
context.close();
}
}
执行的结果,可以看出factoryBean的特殊,因为获取它得多的是DemoBean2,而要获取factory对象本身的话可以直接加&符号,当然也可以直接通过类获取
bean获取就看到这里了,接下来看一下bean的生命周期,有三种实现
方法一:
public class DemoBean implements InitializingBean,DisposableBean { //初始化方法 public void afterPropertiesSet() throws Exception { } //销毁方法 public void destroy() throws Exception { } }
方法二:
@Bean(initMethod = "init",destroyMethod = "destroy") @Scope("prototype") public DemoBean2 createDemoBean2(){ return new DemoBean2(); }
方法三:
@PostConstruct public void init(){ //初始化 } @PreDestroy public void destroy(){ //销毁 }
最近用spring boot,感觉对注解的使用很频繁,就想看看bean的相关源码和实现,这里零散的记录备忘