欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

SprintBoot中如何构造Bean原理分析

发布时间:2025/6/15 编程问答 27 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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原理分析的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。