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