如何在构造函数中使用params自动装配?

时间:2014-01-27 16:09:09

标签: java spring dependency-injection annotations

我有一个我想要@Autowired的服务,但它在构造函数中需要一个复杂的对象。如何使用依赖注入提供它?

@Service
class ProcessService
    @Autowired
    private PersonService service;

    public void run() {
        //create the person dynamically, eg based on some user input
        Person person = new Person("test");

        //new PersonService(person);
        //I used to create the object myself. now switching to spring.
        //how can I get the person object into the service using autowire?
    }
}

@Service
class PersonService {
    public PersonService(Person person) {
        this.person = person; //the object the service can work with
    }
}

3 个答案:

答案 0 :(得分:2)

您应该使用PersonService注释@Autowired的结构函数。

@Service
class PersonService {
    @Autowired
    public PersonService(Person person) {
        this.person = person; //the object the service can work with
    }
}

然后你必须在某处提供Person bean。

但我想Person是从数据库加载的实例。 由于PersonService是一个单例,因此将它绑定到一个Person实例是没有意义的。

在这种情况下,您必须为从db中检索的每个PersonService对象创建一个新的Person实例。

如果您想这样做,那么这也意味着代码会创建PersonService。因此弹簧容器控制,因此弹簧不能自动自动装配。

尽管如此,您可以使用AutowireCapableBeanFactory自动装配已在容器外实例化的bean。但这是一种方式。这些bean将不可用于容器中定义的那些bean。

 AutowireCapableBeanFactory acbf = ...;
 acbf.autowireBean(someInstance);

当我使用hibernate时,我通常使用PostLoadListener自动装配域对象。

但是还有另一种使用aspectj和load-wime编织的方法。看一下spring文档8.4.1

  

如果您需要建议不受Spring容器管理的对象(通常是域对象),那么您将需要使用AspectJ。如果您希望建议除简单方法执行之外的连接点(例如,字段获取或设置连接点等),您还需要使用AspectJ。

答案 1 :(得分:0)

只需在另一个

之上添加一个空构造函数
@Service
class PersonService {

 public PersonService() {

        }

    public PersonService(Person person) {
        this.person = person; //the object the service can work with
    }

 //Getters and setters

}

然后保留其他课程,如果你想打电话给那个人

答案 2 :(得分:0)

将某人设为@Component并将@ConstructorProperties添加到构造函数

@Service
class PersonService {
    @Autowired
    @ConstructorProperties({"person"})
    public PersonService(Person person) {
        this.person = person; //the object the service can work with
    }
}