如何在使用Spring自动接线时传递构造函数参数? [英] How to pass constructor parameter while using spring auto wiring?

查看:136
本文介绍了如何在使用Spring自动接线时传递构造函数参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的项目使用的是Spring DI/IoC,因此我正在使用自动装配来注入豆类.程序需要在实例化过程中将参数传递给对象.而且参数是在运行时(而不是在编译时)知道的.

Our Project is using spring DI/IoC, so i am using autowiring to inject beans. The program needs to pass parameters to an object during it's instantiation. And the parameters are know at run time (not at compile time).

如何在使用自动装配时实现此目的.示例代码如下.

How to achive this while using autowiring. Sample code is as below.

接口- IMessage

package com.example.demo.services;

public interface IMessage {
        String message(String name);
}

实施-
SayHelloService

package com.example.demo.services;

import org.springframework.stereotype.Service;

@Service
public class SayHelloService implements IMessage {

    String id;

    public SayHelloService(String id) {
        super();
        this.id = id;
    }

    @Override
    public String message(String name) {
        return "Hello Dear User - " + name + ". Greeter Id: " + id ;
    }
}

MasterService

package com.example.demo.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class MasterService implements IMessage  {

    String creationTime;

    MasterService() {
        System.out.println("ms... default constructor");
        creationTime = Long.toString(System.currentTimeMillis());
    }

    //classic java way of creating service
    IMessage sayHelloServiceClassicWay = new SayHelloService(creationTime);

    //how to achieve above using spring auto wiring. Below code does not exactly do same.
    @Autowired
    @Qualifier("sayHelloService")
    IMessage sayHelloServiceAutoWired;

    @Override
    public String message(String name) {
        return name.toString();
    }    
}

现在在上述程序中(在MasterService中)如何替换

Now in the above program (in MasterService) how to replace

IMessage sayHelloServiceClassicWay = new SayHelloService(creationTime);

IMessage sayHelloServiceClassicWay = new SayHelloService(creationTime);

具有弹簧等效代码.

推荐答案

Spring无法以这种方式工作.

Spring doesn't work in this way.

您的两个bean在执行和实例化方面都太耦合了:创建第一个bean时,它是在构造期间创建的,第二个bean则在运行时在参数构造函数中传递给它一个生成的值. >

Your two beans are too coupled, both in terms of execution and instantiation : as the first one is created, it created during its construction, the second one and it passes to it a generated value at runtime in argument constructor.

即使使用依赖性注入顺序( @DependsOn

Even by playing with dependency injection order (@DependsOn, @Order or with two @Configuration which one depends on the other) it would not solve your problem because of the runtime generated value that is not a dependency.

作为一种解决方法,可以接受在IMessage界面中提供一次 creationTime值的方法.
SayHelloService可能看起来像:

As a workaround, providing a method to value once creationTime in the IMessage interface may be acceptable.
SayHelloService could look like :

package com.example.demo.services;

import org.springframework.stereotype.Service;

    @Service
    public class SayHelloService implements IMessage {

        String id;

        public SayHelloService(String id) {
            super();
            this.id = id;
        }

        @Override
        public void setId(String id){
            // you can add this check to enforce the immutability of id
            if (this.id != null){//exception handling}
            this.id = id;
        }

        @Override
        public String message(String name) {
            return "Hello Dear User - " + name + ". Greeter Id: " + id ;
        }
    }

您可以通过以下方式更改MasterService:

And you could change MasterService in this way :

private IMessage sayHelloServiceAutoWired;

@Autowired
MasterService( @Qualifier("sayHelloService")
IMessage sayHelloServiceAutoWired) {
    System.out.println("ms... default constructor");
    creationTime = Long.toString(System.currentTimeMillis());
    this.sayHelloServiceAutoWired = sayHelloServiceAutoWired;
    this.sayHelloServiceAutoWired.setId(creationTime);
}

PS:自动装配构造器不是强制性的,但是更干净的是,没有用于设置类依赖关系的API.您也可以使用二传手.

PS : The autowiring constructor is not mandatory but it is cleaner that having no API to set dependencies of the class. You may also use a setter.

这篇关于如何在使用Spring自动接线时传递构造函数参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆