好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

@Autowired注入为null问题原因分析

问题说明

最近看到spring事务,在学习过程中遇到一个很苦恼问题

搭建好spring的启动环境后出现了一点小问题

在启动时候却出现[java.lang.nullpointerexception]

不过因为当时一个小小的疏忽很low的问题 请往下看...

工程结构

代码片段

spring.xml

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<?xml version= "1.0" encoding= "utf-8" ?>

<beans xmlns= "http://www.springframework.org/schema/beans"

   xmlns:xsi= "http://www.w3.org/2001/xmlschema-instance"

   xmlns:context= "http://www.springframework.org/schema/context"

   xsi:schemalocation="

     http: //www.springframework.org/schema/beans

     http: //www.springframework.org/schema/beans/spring-beans.xsd

     http: //www.springframework.org/schema/context

     http: //www.springframework.org/schema/context/spring-context.xsd">

 

   <!-- spring注解扫描 -->

   <context:component-scan base- package = "com.*" />

 

   <!-- 1 . 数据源对象: c3p0连接池 -->

   <bean id= "datasource"

     class = "com.mchange.v2.c3p0.combopooleddatasource" >

     <property name= "driverclass" value= "org.h2.driver" ></property>

     <property name= "jdbcurl"

       value= "jdbc:h2:tcp://192.168.190.1/~/test" ></property>

     <property name= "user" value= "sa" ></property>

     <property name= "password" value= "123" ></property>

   </bean>

 

   <!-- 2 . jdbctemplate工具类实例 -->

   <bean id= "jdbctemplate"

     class = "org.springframework.jdbc.core.jdbctemplate" >

     <property name= "datasource" ref= "datasource" ></property>

   </bean>

 

   <!-- 3 .配置事务 -->

   <bean id= "datasourcetransactionmanager"

     class = "org.springframework.jdbc.datasource.datasourcetransactionmanager" >

     <property name= "datasource" ref= "datasource" ></property>

   </bean>

 

</beans>

test.java

?

1

2

3

4

5

6

7

8

public class test {

   public static void main(string[] args) {

     classpathxmlapplicationcontext classpathxmlapplicationcontext = new classpathxmlapplicationcontext(

         "spring.xml" );

     serviceif service = (serviceif) classpathxmlapplicationcontext.getbean( "serviceimpl" );

     service.add( "小王" , 23 );

   }

}

transactionutil.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

@component ( "transactionutil" )

public class transactionutil {

 

   /**

    * 初始化数据源

    */

   @autowired

   private datasourcetransactionmanager datasourcetransactionmanager;

 

   /**

    * 开启事务

    *

    * @return

    */

   public transactionstatus begin() {

     transactionstatus transaction = datasourcetransactionmanager.gettransaction( new defaulttransactiondefinition());

     system.out.println( " 开启事务成功 " );

     return transaction;

   }

 

   /**

    * 提交事物

    *

    * @param transaction

    */

   public void commit(transactionstatus transaction) {

     datasourcetransactionmanager.commit(transaction);

     system.out.println( " 事物提交成功 " );

   }

 

   /**

    * 回滚事务

    *

    * @param transaction

    */

   public void rollback(transactionstatus transaction) {

     datasourcetransactionmanager.rollback(transaction);

     system.err.println( " 事物进行回滚 " );

   }

}

serviceimpl.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@service ( "serviceimpl" )

public class serviceimpl implements serviceif {

 

   @autowired

   transactionutil transactionutil;

 

   private transactionstatus transactionstatus = null ;

 

   @override

   public void add(string name, integer age) {

     transactionstatus = transactionutil.begin();

     try {

       new daoimpl().add(name, age);

       transactionutil.commit(transactionstatus);

     } catch (exception e) {

       system.err.println( "error >>> 执行出现异常 即将进行回滚操作" );

       transactionutil.rollback(transactionstatus);

     }

   }

}

daoimpl.java

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

public class daoimpl implements daoif{

 

   /**

    * 注入jdbc模板类

    */

   @autowired

   private jdbctemplate jdbctemplate;

 

   /**

    * 第一条插入语句

    */

   private final string sql_insert_01 = "insert into user values (?,?)" ;

 

   /**

    * 添加sql执行

    *

    * @param name

    * @param age

    */

   public void add(string name, integer age) {

     jdbctemplate.update(sql_insert_01, name, age);

   }

}

运行结果

问题分析

解决思路

我在想 为什么会没有注入进来呢 我明明加了@autowired注解

后来猜到可能是spring.xml配置的问题

看完也没有问题

我就从java source一步一步看 发现....

我靠 我就猜测是不是如果用「new object()」的方式创建实例后 其class中的bean的注解会失效呢?

然后我尝试在serviceimpl.java中以注解的方式把daoif的实例注入到serviceimpl,

并在daoimpl.java的类上面添加@repository,

把serviceimpl.java中new daoimpl()替换成注入的daoimpl。

改修代码

serviceimpl.java修改后

daoimpl.java修改后

改修后调试

其实我懂得也不太多 spring注入的流程那

首先他会把项目中target -> classes 目录下的「.class」文件进行解析

通过spring.xml中的「context:component-scan」进行注解扫描

如果这个路径下的「.class」文件的类上面是否存在@component声明的注解

如果被此类注解修饰,spring会把所有被注解修饰的bean进行实例化操作 供给@autowired进行注入

(在spring注解的源码中@service和@repository等等都继承了@component注解)

结论

在使用spring的bean容器时 千万要确保

配置的注解扫描路径正确

jar的依赖是否存在

是否在bean的上面加「@service @repository @component … 」

要细心 遇到异常不要紧 慢慢分析!!!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:http://www.cnblogs.com/cat-/p/10014477.html

查看更多关于@Autowired注入为null问题原因分析的详细内容...

  阅读:11次