【问题标题】:Tapestry: Inject at runtimeTapestry:在运行时注入
【发布时间】:2016-08-22 16:36:56
【问题描述】:

通过了解“挂毯的工作原理”再次遇到一个小问题。

我有一个 Tapestry 组件(在本例中是一个值编码器):

public class EditionEncoder implements ValueEncoder<Edition>, ValueEncoderFactory<Edition> {

    @Inject
    private IEditionManager editionDao;

    public EditionEncoder(IEditionManager editionDao) {
        this.editionManager = editionDao;
    }

    @Override
    public String toClient(Edition value) {
        if(value == null) {
            return "";
        }
        return value.getName();
    }

    @Override
    public Edition toValue(String clientValue) {
        if(clientValue.equals("")) {
            return null;
        }
        return editionManager.getEditionByName(clientValue);
    }

    @Override
    public ValueEncoder<Edition> create(Class<Edition> type) {
        return this;
    }
}

注入管理器不起作用,因为编码器是在这样的页面中创建的:

 public void create() {
        editionEncoder = new EditionEncoder();
  }

因此,我不得不使用这个丑陋的解决方案:

@Inject
private IEditionManager editionmanager;
editionEncoder = new EditionEncoder(editionManager);

有没有更好的方法在运行时注入组件,或者一般来说有更好的解决方案吗?

提前感谢您的帮助,

【问题讨论】:

    标签: java service dependencies code-injection tapestry


    【解决方案1】:

    一旦您使用“new”,tapestry-ioc 就不会参与对象创建并且无法注入。您应该注入所有内容,并且永远不要将“新”用于单例服务。这适用于所有 ioc 容器,而不仅仅是 Tapestry-ioc。

    另外,如果你将@Inject 放在一个字段上,那么你也不需要构造函数来设置它。做一个或另一个,永远不要两者兼而有之。

    你应该这样做:

    public class MyAppModule {
        public void bind(ServiceBinder binder) {
            binder.bind(EditionEncoder.class);
        }
    }
    

    然后在你的页面/组件/服务中

    @Inject EditionEncoder editionEncoder;
    

    如果你想把你自己的实例化对象放在那里,你可以这样做

    public class MyServiceModule {
        public void bind(ServiceBinder binder) {
            binder.bind(Service1.class, Service1Impl.class);
            binder.bind(Service2.class, Service2Impl.class);
        }
        public SomeService buildSomeService(Service1 service1, Service2 service2, @AutoBuild Service3Impl service3) {
            Date someDate = new Date();
            return new SomeServiceImpl(service1, service2, service3, someDate);
        }
    }
    

    【讨论】:

    • 是的,这对我来说很清楚。但是例如在 spring 中,可以使用手动实例化对象“强制”注入机制。我正在寻找一种类似的方式。我不喜欢构造函数参数的方式。
    猜你喜欢
    • 1970-01-01
    • 2012-02-27
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多