怎么在springboot中手动注入bean
创始人
2024-12-29 15:42:05
0次

1、springboot启动类实现接口ApplicationListener,实现方法onApplicationEvent,初始化上下文

package test.projectTest;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.system.ApplicationPidFileWriter;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import test.projectTest.util.SpringContextUtil;
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class, MybatisAutoConfiguration.class})
@SpringBootApplication(scanBasePackages={"test.projectTest"})
public class TestApplication implements ApplicationListener
{
 public static void main( String[] args )
 {
  SpringApplication application = new SpringApplication(TestApplication.class);
  application.addListeners(new ApplicationPidFileWriter());
  application.run(args);
  System.out.println( "启动成功" );
 }
 @Override
 public void onApplicationEvent(ContextRefreshedEvent event) {
  SpringContextUtil.setApplicationContext(event.getApplicationContext());  
 }
}

2.SpringContextUtil工具类初始化ApplicationContext applicationContext

package test.projectTest.util;
import org.springframework.context.ApplicationContext;
/**
 * 获取spring容器,以访问容器中定义的其他bean
 */
public class SpringContextUtil{
 //spring上下文
 private static ApplicationContext applicationContext;
 
 /**
  * 实现ApplicationContextAware接口的回调方法,设置上下文环境
  * @param applicationContext
  */
 public static void setApplicationContext(ApplicationContext applicationContext){
  if(null==SpringContextUtil.applicationContext)
   SpringContextUtil.applicationContext=applicationContext;
 }
 
 public static ApplicationContext getApplicationContext(){
  return applicationContext;
 }
  /**
  * 通过name获取 Bean.
  *
  * @param name
  * @return
  */
 public static Object getBean(String name) {
  return getApplicationContext().getBean(name);
 }
 /**
  * 通过name获取 Bean.
  *
  * @param clazz
  * @return
  */
 public static  T getBean(Class clazz) {
  return getApplicationContext().getBean(clazz);
 }
 /**
  * 通过name,以及Clazz返回指定的Bean
  *
  * @param name
  * @param clazz
  * @return
  */
 public static  T getBean(String name, Class clazz) {
  return getApplicationContext().getBean(name, clazz);
 }
}

3.获取bean

package test.projectTest.util;
import test.projectTest.mapper.slave.DailyDataMapper;
public class TestUtil{ 
 private static DailyDataMapper dailyDataMapper; 
 static{//手动注入bean
  if(dailyDataMapper==null){
   dailyDataMapper = (DailyDataMapper)SpringContextUtil.getBean("dailyDataMapper");
  }
 }
 public static void test(){
  dailyDataMapper.selectByPrimaryKey(1);
 } 
}

补充:springboot中bean的实例化和属性注入过程

springboot版本(2.0.4 RELEASE)

大致描述springboot中bean的实例化和属性注入过程流程

1) 在某一时刻Spring调用了Bean工厂的getBean(beanName)方法。beanName可能是simpleController,或者simpleService,simpleDao,顺序没关系(因为后面会有依赖关系的处理)。我们假设simpleController吧

2)getBean方法首先会调用Bean工厂中定义的getSingleton(beanName)方法,来判断是否存在该名字的bean单例,如果存在则返回,方法调用结束(spring默认是单例,这样可以提高效率)

3) 否则,Spring会检查是否存在父工厂,如果有则返回,方法调用结束

4) 否则,Spring会检查bean定义(BeanDefinition实例,用来描述Bean结果,component-scan扫描后,就是将beanDefinition实例放入Bean工厂,此时还没有被实例化)是否有依赖关系,如果有,执行1)步,获取依赖的bean实例

5) 否则,Spring会尝试创建这个bean实例,创建实例前,Spring会检查调用的构造器,并实例化该Bean,(通过Constructor.newInstance(args)进行实例化)

6) 实例化完成后,Spring会调用Bean工厂的populateBean方法来填充bean实例的属性,也就是自动装配。populateBean方法便是调用了BeanPostProcessor实例来完成属性元素的自动装配工作

7)在元素装配过程中,Spring会检查被装配的属性是否存在自动装配的其他属性,然后递归调用getBean方法,知道所有@Autowired的元素都被装配完成。如在装配simpleController中的simpleService属性时,发现SimpleServiceImpl实例中存在@Autowired属性simpleDao,然后调用getBean(simpleDao)方法,同样会执行1)----7)整个过程。所有可以看成一个递归过程。

8)装配完成后,Bean工厂会将所有的bean实例都添加到工厂中来。

Bean的实例化

1. 进入SpringApplication类中refreshContext()方法

怎么在springboot中手动注入bean

2. 进入AbstractApplicationContext类中refresh()方法,找到this.finishBeanFactoryInitialization()方法,这个方法就是完成beanFactory的实例化

怎么在springboot中手动注入bean

3. 进入AbstractApplicationContext类中finishBeanFactoryInitialization()方法,找到preInstantiateSingletons()

怎么在springboot中手动注入bean

4. 进入DefaultListableBeanFactory类中preInstantiateSingletons()方法,找到getBean()方法

怎么在springboot中手动注入bean

5. 进入AbstractBeanFactory类中getBean()方法,找到doGetBean()方法

怎么在springboot中手动注入bean

6. 在AbstractBeanFactory类中doGetBean方法中,找到createBean()方法

怎么在springboot中手动注入bean

7. 进入AbstractAutowireCapableBeanFactory类中createBean方法中,找到doCreateBean()方法

怎么在springboot中手动注入bean

8. 在AbstractAutowireCapableBeanFactory类中doCreateBean()方法中,找到createBeanInstance()方法,看名字就知道是实例化bean的

怎么在springboot中手动注入bean

9. 在AbstractAutowireCapableBeanFactory类createBeanInstance()方法中,找到instantiateBean()方法

怎么在springboot中手动注入bean

10. 在AbstractAutowireCapableBeanFactory类instantiateBean()方法中,找到instantiate()方法

怎么在springboot中手动注入bean

11. 在SimpleInstantiationStrategy类instantiate()方法中,找到instantiateClass()方法

怎么在springboot中手动注入bean

12. 在BeanUtils类instantiateClass()方法中,可知bean的实例化是通过Constructor.newInstance()进行实例化

怎么在springboot中手动注入bean

Bean的属性注入

1. 在AbstractAutowireCapableBeanFactory类doCreateBean()方法中,找到populateBean()方法,从名字可知是用来填充bean的

怎么在springboot中手动注入bean

2. 在AbstractAutowireCapableBeanFactory类中populateBean()方法,找到postProcessPropertyValues()方法

怎么在springboot中手动注入bean

3. 进入AutowiredAnnotationBeanPostProcessor类中postProcessPropertyValues()方法中,找到findAutowiringMetadata()方法,在这个方法中,如果属性中含有@Autowired注解则会递归getBean()。没有然后进入inject()方法中

怎么在springboot中手动注入bean

4. 进入AutowiredAnnotationBeanPostProcessor类inject方法中,找到resolveDependency()方法,通过这个方法获取对应字段的值

怎么在springboot中手动注入bean

5. 进入AutowiredAnnotationBeanPostProcessor类inject方法中,找到field.set(bean, value)方法,通过反射将值设置到属性中

怎么在springboot中手动注入bean

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...