由於最近在研究學習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的相關源碼和實現,這裏零散的記錄備忘