必须使用ApplicationContext获取实例的一种情况

182 阅读1分钟

默认情况下,在Spring框架中获取容器中的实例可以用注解@Autowire或者使用 ApplicationContext提供的getBean()方法,今天在读代码时,遇到了一种情况,不得不用ApplicationContext来获取实例

代码

业务实现类(可以看到Task对象是调用context.getBean()获取的)

@Service
public class ConsumeServiceImpl implements ConsumeService {
    @Autowired
    private ApplicationContext context;

    @Override
    public void consume2Send(List<TaskInfo> taskInfoLists) {
        for (TaskInfo taskInfo : taskInfoLists) {
            Task task = context.getBean(Task.class).setTaskInfo(taskInfo);
            //省略其他代码...
        }
    }
}

Task类

@Data
@Accessors(chain = true)
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Task implements Runnable {
    private TaskInfo taskInfo;

    @Override
    public void run() {
        //业务代码略
    }
}

分析

  1. 为什么一定要用ApplicationContext,而不能用@Autowire获取Task对象?
    • 首先Task类上的注解@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)标识Task为多实例的,因此每次注入容器中的Task对象都是新的。
    • 而业务实现类只是加了@Service注解,默认情况下,Spring容器中的对象是单例的,因此这个service实现类也是单例的,在一个单例的对象中想获取多例对象,就要使用ApplicationContext每次都获取一个新的实例。
  2. Task类上的@Accessors(chain = true)注解是做什么用的?
    • lombok提供的注解,表示调用这个类中某个字段的setter方法时返回当前对象,在这个例子中,调用setTaskInfo()方法会返回Task对象。