spring 容器實現對bean的管理(註解方式解析,源碼閱讀)

由於最近在研究學習spring boot,因此這裏想詳細學習回顧了一下spring 容器對bean的一些管理方式和部分源碼學習。java

首先初始類AnnotationConfigApplicationContext,簡單源碼查看,支持兩個參數一個爲掃描,一個爲傳遞配置類,這裏咱們使用的第一個spring

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        this();
        this.register(annotatedClasses);
        this.refresh();
    }

    public AnnotationConfigApplicationContext(String... basePackages) {
        this();
        this.scan(basePackages);
        this.refresh();
    }

下面在上面的基礎上進行擴展學習,首先看一下要分析的源碼json

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名稱ui

方法三:經過Factorybean實現this

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對象自己的話能夠直接加&符號,固然也能夠直接經過類獲取prototype

bean獲取就看到這裏了,接下來看一下bean的生命週期,有三種實現code

方法一:對象

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的相關源碼和實現,這裏零散的記錄備忘

相關文章
相關標籤/搜索