美文网首页
@Import 注解调用流程一

@Import 注解调用流程一

作者: simians | 来源:发表于2022-05-21 17:09 被阅读0次

    首先 @Import value 里的值通常是带有@configuration或者实现ImportBeanDefinitionRegistrar,ImportSelector接口 这几种。
    如果是普通的业务类呢会怎么样?比如只是添加@Component 或者@Service 之类的呢?甚至这个类就没有交给spring 管理的呢?

    package com.spring.demo.service.impl;
    
    import com.spring.demo.service.TestService;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Service;
    /**
     * @author haoran
     */
    @Service
    public class TestServiceImpl  implements TestService , InitializingBean {
    
        public void init(){
            System.out.println("this is postConstruct method");
        }
        public TestServiceImpl(){
            System.out.println("调用 TestService ------");
        }
        public void helloSpring(){
            System.out.println("hello Spring");
        }
    
        @Override
        public void sendMessage(String message) {
            System.out.println("hello! "+message);
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("this is InitializingBean");
        }
    }
    /**
     * @author haoran
     */
    @Configuration(proxyBeanMethods = false)
    @ComponentScan(value = "com.spring")
    //@RemoteScan(url = "com.spring.demo.api")
    @Import(TestServiceImpl.class)
    public class Config {
    }
    
    /**
     * @author haoran
     */
    public class TestMain {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class);
            TestService testService =  annotationConfigApplicationContext.getBean(TestService.class);
            testService.sendMessage("1111");
        }
    }
    
    输出结果
    > Task :spring-demo:TestMain.main()
    调用 TestService ------
    this is InitializingBean
    hello! 1111
    
    BUILD SUCCESSFUL in 5s
    
    

    由此看来 import value 里是业务类也是没有问题的
    如果我去掉@Service 注解呢,会怎么样呢

    /**
     * @author haoran
     */
    //@Service
    public class TestServiceImpl  implements TestService , InitializingBean {
    
        public void init(){
            System.out.println("this is postConstruct method");
        }
        public TestServiceImpl(){
            System.out.println("调用 TestService ------");
        }
        public void helloSpring(){
            System.out.println("hello Spring");
        }
    
        @Override
        public void sendMessage(String message) {
            System.out.println("hello! "+message);
        }
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("this is InitializingBean");
        }
    }
    > Task :spring-demo:TestMain.main()
    调用 TestService ------
    this is InitializingBean
    hello! 1111
    

    执行结果是没有问题的
    那由此可以盲猜 @import 注解有@Compontent 作用,也就是说可以将value 里的类交给spring 管理。
    那我就尝试下跟中源码看下,@Import 到底是在何时将该类交给spring 管理的


    processConfigBeanDefinitions prase.png
    processConfigurationClass.png
    asSourceClass.png
    doprocessConfigurationClass.png image.png processImports.png

    最后一行红字是错误的这里并没有将TestServiceImpl 注册到Spring里


    processConfigurationClass.png image.png
    image.png
    image.png
    image.png
    image.png

       @Import注解value 类的注入算是执行完成了,虽然TestServiceImpl 类被作为了带有@configuration 注解的类但是它并不完全等于带有@Configuration 的类,这个类是没有被增强的 一般带有@Configuration 注解的类 是会被spring 增强为代理类 即被cglib 代理。关于这些可以看下往期相关的文章。
      至此可以的出结论 @Import 可以将一个不被spring 管理的类 变为spring 管理的类,即将value 里所引用的类注册到spring。
      总结:开始spring 在解析config 类的时候 查到有个引用类@import(value= TestServiceImpl.class) 并将TestServiceImpl 作为ConfigClass(即带有@Configuration 的类) 放入到一个list 里 当config 解析完成后会调用一个loadBeanDefinitions(configClasses) 方法 加载扫描的配置类集合 将这些类转换为BeanDefinition 紧接着调用registerBeanDefinition() 方法注册到beanDefinitionMap 里至此TestServiceImpl.class 的注册到beanDefinitionMap里的步骤就结束了 后续就是普通的Bean 的流程。

    相关文章

      网友评论

          本文标题:@Import 注解调用流程一

          本文链接:https://www.haomeiwen.com/subject/wfifprtx.html