关于@autowired的一点点理解

这一切的一切都源于一个NPE(NULL POINTER EXCEPTION)。

有这样几个类,

@Service

public class TestService{

      @autowired

       private  Testdao   testDao;

      public void aaa(){

            testDao.query();

      }

}

@Repository

public class TestDao{}

public  class  TestUtil{

        public static void  ttt(){

              TestService   ts  =  new  TestService();

              ts.aaa();

        }

}

当调用util时,就会报dao的空指针,问题描述完了。

下面有几点分析(是我经过反复测试得出来的):

1. 为什么会空指针,难道没有注入进去?

答案是已经注入进去了。

2. 为什么已经注入进去了?

这要从服务器启动和spring扫描包开始说起,在服务器启动的时候,spring会将扫描包下的类得到一个实例bean, 然后交由spring统一管理; 比如, 扫描了service层,然后有@Service, 那么spring容器中就会有一个bean id="testService", 你 getBean的时候就能得到这个bean实例, dao层 controller层同理;

那么@autowired这个注解,spring是什么时候发现的呢?   其实就是在扫描service的过程中。   扫描service,首先会得到实例,(这个时候如果TestService中构造器有打印语句,就会打印出来,说明是实例化了),然后接着就会识别到@Autowired注解,

这时会把之前扫描dao得到的实例注入到这个成员变量里面(也就是赋值给private  Testdao   testDao;)。

 

这时会涉及到另一个问题,  那么扫描dao是不是必须在扫描service之前?  

答案是不一定。   因为我们在配置扫描包的时候有两个地方可以配置: 第一个地方是在spring.xml中, 第二是spring-mvc.xml中;而在这两个地方配置的话,情况是不同的;

在spring中配置的时候,必须按照顺序来,即先扫描dao, 再扫描service,  否则,在扫描service的时候,就会找不到dao对应的实例,  spring就会报错,无法完成注入,应至少有一个dao对应的实例;

在spring-mvc配置的时候就不需要顺序了,扫描controller、service、dao可以不按照顺序来,是不会报错的;

 

3. 既然已经注入进去了,那么为什么还是null?

方式一: TestService   ts  =  new  TestService(); ts.aaa();    

方式二:

ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:conf/spring.xml");

TestService   ts =  ac.getBean("testService");    ts.aaa();  

测试之后会发现方式二是不会报空指针的。

我猜, @Service的testService 和@Autowired的 testDao是有联系的。

扫描service包的时候,spring发现@Service,会产生一个 id 为testService 的bean; 几乎同时会识别到@Autowired,然后去容器中取 id为 testDao的bean,赋值给成员变量@autowired private  Testdao   testDao;  关键的地方在于这个被赋值的成员变量testDao,是属于实例 id 为testService 的bean的;  通过new  TestService()得到的实例下的成员变量仍然是空;

所以,关键就在于两者的实例是不同的。所以在工具类中使用service的正确打开方式应该是用getBean的方式。

 

4. 扫描包可以放在两个地方,那么怎么放比较好?

个人认为,直接放在spring-mvc.xml就可以。  new FileSystemXmlApplicationContext("classpath:conf/spring-mvc.xml");

也是可以取到bean的。 这样说来,spring.xml中就什么都不放了。

 

以上内容,个人理解,仅供参考,如有雷同,纯属巧合。    欢迎批评与指正,互相学习与进步。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值