1、springboot启动类实现接口applicationlistener<contextrefreshedevent>,实现方法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<contextrefreshedevent>
{
 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> t getbean(class<t> clazz) {
  return getapplicationcontext().getbean(clazz);
 }
 /**
  * 通过name,以及clazz返回指定的bean
  *
  * @param name
  * @param clazz
  * @return
  */
 public static <t> t getbean(string name, class<t> 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()方法

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

3. 进入abstractapplicationcontext类中finishbeanfactoryinitialization()方法,找到preinstantiatesingletons()

4. 进入defaultlistablebeanfactory类中preinstantiatesingletons()方法,找到getbean()方法

5. 进入abstractbeanfactory类中getbean()方法,找到dogetbean()方法

6. 在abstractbeanfactory类中dogetbean方法中,找到createbean()方法

7. 进入abstractautowirecapablebeanfactory类中createbean方法中,找到docreatebean()方法

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

9. 在abstractautowirecapablebeanfactory类createbeaninstance()方法中,找到instantiatebean()方法

10. 在abstractautowirecapablebeanfactory类instantiatebean()方法中,找到instantiate()方法

11. 在simpleinstantiationstrategy类instantiate()方法中,找到instantiateclass()方法

12. 在beanutils类instantiateclass()方法中,可知bean的实例化是通过constructor.newinstance()进行实例化

bean的属性注入

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

2. 在abstractautowirecapablebeanfactory类中populatebean()方法,找到postprocesspropertyvalues()方法

3. 进入autowiredannotationbeanpostprocessor类中postprocesspropertyvalues()方法中,找到findautowiringmetadata()方法,在这个方法中,如果属性中含有@autowired注解则会递归getbean()。没有然后进入inject()方法中

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。如有错误或未考虑完全的地方,望不吝赐教。