Spring注入方式以及循环依赖

公司最新的项目要引入阿里规约,业务层注入属性的方式从原来的属性注入变成了Spring4推荐的构造器注入,代码的不规范导致我出现了循环引用的问题:

是这两个地方出现了问题

TaskImageService

package service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdls.carp.business.dao.TaskImageDao;
import com.cdls.carp.business.entity.TaskImageEntity;
import com.cdls.carp.business.service.TaskImageService;
import com.cdls.carp.business.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TaskImageServiceImpl extends ServiceImpl<TaskImageDao, TaskImageEntity> implements TaskImageService {

    private final TaskService taskService;

    @Autowired
    public TaskImageServiceImpl(TaskService taskService) {
        this.taskService = taskService;
    }
}

TaskService

package  service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdls.carp.business.dao.TaskDao;
import com.cdls.carp.business.service.TaskImageService;
import com.cdls.carp.business.service.TaskLogService;
import com.cdls.carp.business.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class TaskServiceImpl extends ServiceImpl<TaskDao, TaskEntity> implements TaskService {

    private final TaskImageService taskImageService;

    @Autowired
    public TaskServiceImpl(TaskImageService taskImageService) {
        this.taskImageService = taskImageService;
    }
}

于是我使用属性注入的方式

TaskImageService

package service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdls.carp.business.dao.TaskImageDao;
import com.cdls.carp.business.entity.TaskImageEntity;
import com.cdls.carp.business.service.TaskImageService;
import com.cdls.carp.business.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TaskImageServiceImpl extends ServiceImpl<TaskImageDao, TaskImageEntity> implements TaskImageService {

    @Autowired
    private TaskService taskService;

}

TaskService

package  service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cdls.carp.business.dao.TaskDao;
import com.cdls.carp.business.service.TaskImageService;
import com.cdls.carp.business.service.TaskLogService;
import com.cdls.carp.business.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class TaskServiceImpl extends ServiceImpl<TaskDao, TaskEntity> implements TaskService {

    @Autowired
    private TaskImageService taskImageService;

}

结果又可以运行了,我当时怀疑Spring Ioc的问题,后来才发现其实是类的实例机制出现了错误,我们举个例子,

有两个类,分别是TestA 和 TestB,他们都拥有对方的属性

/**
 * @author Tobu
 */
public class TestA {

    private TestB testB;

    public TestA() {
    }

    public TestA(TestB testB) {
        this.testB = testB;
    }

    public void setTestB(TestB testB) {
        this.testB = testB;
    }
}
/**
 * @author Tobu
 */
public class TestB {

    private TestA testA;

    public TestB() {
    }

    public TestB(TestA testA) {
        this.testA = testA;
    }

    public void setTestA(TestA testA) {
        this.testA = testA;
    }
}

例如我们现在需要TestA,我现在是用构造器来创建TestA

恍然大悟,如果是这样的话我确实是进行了循环注入,如果我使用默认的空构造器,那么就不再是构造器注入而是setter注入了,

解决方式就是把业务逻辑挪到其中的一个类中,就不会出现循环注入的问题

setter注入(空构造器+set方法):

/**
 * @author Tobu
 */
public class TestMain {

    public static void main(String[] args) {

        TestA testA = new TestA();
        
        testA.setTestB(new TestB());
    }
}

属性注入(使用反射机制)

import java.lang.reflect.Field;

/**
 * @author Tobu
 */
public class TestMain {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {

        //  创建testA对象
        TestA testA2 = new TestA();

        //  返回testA
        Class<TestA> testA = (Class<TestA>) Class.forName("TestA");

        //  获取所有的属性
        Field[] fields = testA.getDeclaredFields();

        //  设置属性可以操作并且设置值
        fields[0].setAccessible(true);
        fields[0].set(testA2, new TestB());

        //  实例化对象
        TestA testA1 = testA.newInstance();

    }
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值