67. @Transactional的类注入失败【从零开始学Spring Boot】

来源:互联网 发布:淘宝店策划方案 编辑:程序博客网 时间:2024/06/08 04:00

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

       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

 */

public interface IBaseTestService {

    public void sayHello();

}

 

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

package com.kfit.demo.test;

 

import javax.transaction.Transactional;

 

/**

 * 基本接口实现

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

 * @version v.0.1

 * @date 2016725下午10:21:41

 */

public class BaseTestService implements IBaseTestService{

 

    @Transactional

    public void sayHello() {

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

    }

}

 

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

package com.kfit.demo.test;

 

import org.springframework.stereotype.Service;

 

/**

 * 测试类;

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

 * @version v.0.1

 * @date 2016725下午10:23:11

 */

@Service

public class TestService extends BaseTestService{

   

}

 

测试类引用:

@Autowired

private TestService testService;

 

调用: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

 */

public interface TestService extends IBaseTestService{

   

}

 

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

package com.kfit.demo.test;

 

import org.springframework.stereotype.Service;

 

/**

 * 测试类;

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

 * @version v.0.1

 * @date 2016725下午10:23:11

 */

@Service

public class TestServiceImpl extends BaseTestService implements TestService{

   

}

 

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

 

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

#开启CGLIB动态代理模式

spring.aop.proxy-target-class=true

 

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

 

0 0
原创粉丝点击