SprintBoot中如何构造Bean原理分析
2019獨角獸企業重金招聘Python工程師標準>>>
MySpringBoot打算構造加入Bean的功能,代碼完成,下面解釋操作&原理。
-----------------------------------------------------------------------------
獲取Bean有2種方法,
1)拿到Web容器里的ApplicationContext,調用getBean(Class)方法
2)直接在類里使用Autowired注解
-----------------------------------------------------------------------------
下面就來解釋這2點
1)拿到ApplicationContext,代碼調用getBean
寫上1個類
package helper;import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component;import controller.UserExample;//使用方法 //在任何類中調用 //YourClass aaa=(YourClass) BeanContextHelper.getApplicationContext().getBean(YourClass.class);@Component public class BeanContextHelper implements ApplicationContextAware {private static ApplicationContext applicationContext = null;@Overridepublic void setApplicationContext(ApplicationContext context) throws BeansException {if (null == applicationContext) {applicationContext = context;}System.out.println("setApplicationContext invoked...");}public static ApplicationContext getApplicationContext() {return applicationContext;} }這個類所在的package必須在boot main類的scan路徑內。
然后setApplicationContext的方法會被調用,我們看一下調用棧
at helper.BeanContextHelper.setApplicationContext(BeanContextHelper.java:21)at org.springframework.context.support.ApplicationContextAwareProcessor.invokeAwareInterfaces(ApplicationContextAwareProcessor.java:121)at org.springframework.context.support.ApplicationContextAwareProcessor.postProcessBeforeInitialization(ApplicationContextAwareProcessor.java:97)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:409)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1620)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)at server.Boot.main(Boot.java:13)為什么會觸發到這個函數呢?
private void invokeAwareInterfaces(Object bean) {if (bean instanceof Aware) {if (bean instanceof EnvironmentAware) {((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware) bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationContextAware) {//原因在這里((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}}}其實也就是,對于單例的bean,web啟動時,預先構造,然后做一些初始化操作。
因為上面這個類implements ApplicationContextAware接口,所以會執行最后1行代碼。
所以,如果你在任何類里面寫上
FirstBean bean = (FirstBean) BeanContextHelper.getApplicationContext().getBean(FirstBean.class); System.out.println(bean);就會拿到這個Bean的單例對象。
?
2)通過@Autowired注解
這個是自動裝配,讓我們看如何實現的。
假設我們有這么1個Controller類,代碼如下:
package controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;import bean.FirstBean;@RestController @RequestMapping("/user") public class UserExample {public UserExample() {System.out.println("user example . bean --->"+bean);new Exception().printStackTrace();}@SuppressWarnings("unused")@Autowiredprivate FirstBean bean;@RequestMapping(value = "/hi", method = { RequestMethod.GET })public String index() {return "{\"hello\":\"world\"}";} }我們看到有1個Autowired注解,什么時候發揮作用的呢?
想找到這個很簡單,注入一個prototype的類,打印這個prototype的棧就可以了。
嘗試一把,確實可以,注入屬性的位置是
at bean.ProtoTypeBean.<init>(ProtoTypeBean.java:10)at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor.newInstance(Constructor.java:423)at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:142)at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:89)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1147)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1099)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)at server.Boot.main(Boot.java:13)這樣就找到了注入屬性的位置,屬性就是這樣注入的。
?
轉載于:https://my.oschina.net/qiangzigege/blog/905985
總結
以上是生活随笔為你收集整理的SprintBoot中如何构造Bean原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【笔记】与Android选项卡一周
- 下一篇: Java Date Time 教程-ja