67. @Transactional的类注入失败

【从零开始学习SpirngBoot—常见异常汇总】

       Spring的代理模式有两种:java自带的动态代理模式和cglib代理模式,cglib代码模式适用于没有接口的类,而java自带适用于接口类,默认情况下spring boot或者spring 采用接口类的代理模式,如果我们是基于接口编程的,是不会发生问题的,但是如果我们定义了一个class类继承Base类的时候就会出问题了。如下代码就会出现问题:

基本接口类com.kfit.demo.test.IBaseTestService:

package com.kfit.demo.test;

 

/**

 *定义基本接口类;

 *@author Angel(QQ:412887952QQ交流群:193341332)

 *@version v.0.1

 *@date 2016725下午10:20:45

 */

publicinterface IBaseTestService{

    publicvoid sayHello();

}

基本接口实现com.kfit.demo.test.BaseTestService:

package com.kfit.demo.test;

 

importjavax.transaction.Transactional;

 

/**

 *基本接口实现

 *@author Angel(QQ:412887952QQ交流群:193341332)

 *@version v.0.1

 *@date 2016725下午10:21:41

 */

publicclass BaseTestServiceimplementsIBaseTestService{

 

    @Transactional

    publicvoid sayHello() {

       System.out.println("BaseTestService.sayHello()");

    }

}

测试服务类com.kfit.demo.test.TestService:

package com.kfit.demo.test;

 

importorg.springframework.stereotype.Service;

 

/**

 *测试类;

 *@author Angel(QQ:412887952QQ交流群:193341332)

 *@version v.0.1

 *@date 2016725下午10:23:11

 */

@Service

publicclass TestServiceextends BaseTestService{

   

}

测试类引用:

@Autowired

privateTestServicetestService;

 

调用:testService.sayHello();

执行以上我们编写的代码,是会抛出异常的,无法找到TestService实体类。

       那么这个就是由于Spring Boot默认使用了Java自带的动态代理模式(接口代理)。

我们要怎么修改呢?有两种方案遵循接口模式编程:

第一种方案:将上面的TestService修改为接口,然后添加一个TestService的实现类。代码如下:

com.kfit.demo.test.TestService 修改为接口,代码如下:

package com.kfit.demo.test;

 

/**

 *测试类;

 *@author Angel(QQ:412887952QQ交流群:193341332)

 *@version v.0.1

 *@date 2016725下午10:23:11

 */

publicinterface TestServiceextendsIBaseTestService{

   

}

TestService接口的实现类com.kfit.demo.test.TestServiceImpl:

package com.kfit.demo.test;

 

importorg.springframework.stereotype.Service;

 

/**

 *测试类;

 *@author Angel(QQ:412887952QQ交流群:193341332)

 *@version v.0.1

 *@date 2016725下午10:23:11

 */

@Service

publicclassTestServiceImpl extends BaseTestServiceimplements TestService{

   

}

在运行测试代码,完美运行。

第二种方法就是修改SpringBoot的默认动态代理模式,我们刚才说了默认的是Java的动态代理模式,我们只需要修改为CGLIB动态代码模式即可,只需要在application.properties加入如下配置:

#开启CGLIB动态代理模式

spring.aop.proxy-target-class=true

重新运行测试代码,也可完美运行。

购买完整视频,请前往:http://www.mark-to-win.com/TeacherV2.html?id=287