如何在运行时指定构造函数参数时自动装配?

时间:2018-02-16 14:29:47

标签: spring-boot inversion-of-control ioc-container autowired

我有一个域类,我想将其注入到其模块的外观中,该类具有在运行时指定的构造函数参数。该类的定义如下所示:

@Component("area")
@Scope("prototype")
public class GeographicalCircleArea {
    private Location center;
    private double radius;

    private final IShopsProviderAdapter shopsProviderAdapter;

    @Autowired
    GeographicalCircleArea(double centerLatitude, double centerLongitude, double radiusInKm, IShopsProviderAdapter shopsProviderAdapter) {
        this.center = makeCenter(centerLatitude, centerLongitude);
        this.radius = radiusInKm;
        this.shopsProviderAdapter = shopsProviderAdapter;
    }

    List<Shop> getShopsWithin() {
        return shopsProviderAdapter.findShopsWithin(this);
    }

    public Location getCenter() {
        return center;
    }

    public double getRadius() {
        return radius;
    }

    private Location makeCenter(double latitude, double longitude) {
        return new Location(latitude, longitude);
    }
}

我想要注入先例bean的外观是:

@Service
public class GeolocationInformationSystem {

    @Autowired
    private GeographicalCircleArea area;

    public List<Shop> searchForNearbyShops(double centerLatitude, double centerLongitude, double radiusInKm) {
        return area.getShopsWithin();
    }
}

获取在运行时实例化GeographicalCircleArea的参数。 如何正确应用自动装配?

1 个答案:

答案 0 :(得分:0)

在文档中,他们明确指出:

  

对于每个bean,如果使用的是依赖于普通构造函数的,那么它的依赖关系将以属性,构造函数参数或static-factory方法的参数的形式表示。 实际创建bean时,会向bean提供这些依赖项。

这意味着在运行时运行任何代码之前应用程序崩溃的原因是:

 @Autowired
private GeographicalCircleArea area;

由于在容器初始化过程和bean创建步骤

期间未知值未知,因此无法注入未知值的简单原因

如何解决这个问题:通过更改构造函数来改变实现

@Autowired
GeographicalCircleArea(IShopsProviderAdapter shopsProviderAdapter) {

    this.shopsProviderAdapter = shopsProviderAdapter;
}

并更改

 List<Shop> getShopsWithin() {
    return shopsProviderAdapter.findShopsWithin(this);
}

采取这些论点:

List<Shop> getShopsWithin(double centerLatitude, double centerLongitude, 
        double radiusInKm) {
    this.center = makeCenter(centerLatitude, centerLongitude);
    this.radius = radiusInKm;
    return shopsProviderAdapter.findShopsWithin(this);
}