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选项卡一周
- 下一篇: other-如何可以查看别人请求的输出结