简体   繁体   English

在spring中使用构造函数中的autowired依赖项

[英]Using autowired dependency in constructor in spring

I have class NetworkUsageService which uses NetworkUsageMapper to access a database. 我有类的NetworkUsageService,它使用NetworkUsageMapper来访问数据库。 Mapper class is autowired to the service class. Mapper类自动连接到服务类。

I need to access the database during the construcion of service class, so I do something like this: 我需要在构造服务类的过程中访问数据库,所以我这样做:

private int someField;    

@Autowired
private NetworkUsageMapper networkUsageMapper;


public NetworkUsageService() {
    someField = networkUsageMapper.getSomeResultFromDB();
}

However, this doesn't seem to work as I get exception while creating the service bean. 但是,这似乎不起作用,因为我在创建服务bean时遇到异常。 Is there a way to use an autowired dependency during the construction of an object? 有没有办法在构造对象时使用自动连接的依赖?

EDIT: this is my beans configuration as requested: 编辑:这是我的bean配置按要求:

<context:component-scan base-package="mypackage" />
<mybatis:scan base-package="mypackage.mappers" />

<mvc:annotation-driven />

<context:property-placeholder location="classpath:/jdbc.properties"/>

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mapperLocations" value="classpath:mappers/*.xml" />
    <property name="typeAliasesPackage" value="mypackage.transfer" />
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean>

<bean  id="dataSource"
       class="org.springframework.jdbc.datasource.DriverManagerDataSource">

    <property name="driverClassName" value="${jdbc.driverClassName}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

Instead of doing a lot of work in the constructor (and potentially introduce problems because the application tries to go to the database when it isn't fully initialized) it's probably better to do this initialization in a different method and annotate this with @PostConstruct . 而不是在构造函数中做很多工作(并且可能因为应用程序在未完全初始化时尝试转到数据库而引入问题),最好在不同的方法中进行初始化并使用@PostConstruct进行注释。 This way you know for sure your application is completely wired before networkusermapper is called. 通过这种方式,您可以确保在调用networkusermapper之前,应用程序已完全连线。

That's correct. 那是对的。 The bean is first constructed, then the dependencies are injected. 首先构造bean,然后注入依赖项。 If you need it in your constructor, do this 如果您在构造函数中需要它,请执行此操作

@Autowired
public NetworkUsageService(NetworkUsageMapper mapper){
// do stuff
}

The other way is to make the setterMethod of NetworkUsageMapper annotated with @Required annotation 另一种方法是使用@Required注释对NetworkUsageMapper的setterMethod进行注释

@Required
public void setNetworkUsageMapper(NetworkUsageMapper mapper){
this.networkUsageMapper = mapper;
this.someField = this.networkUsageMapper.getSomeResultFromDB();
}

This method would be invoked immediately compulsorily after construction of the object. 在构造对象之后,将立即强制调用此方法。 This is really useful when you have a long list of mandatory properties for the object to work properly. 当您拥有一长串强制属性以使对象正常工作时,这非常有用。 Instead of having the constructor with long parameter list, we can set all the properties using setters with @Required annotation. 我们可以使用带有@Required注释的setter设置所有属性,而不是使用具有长参数列表的构造函数。 It seems to be very handy for me. 这对我来说似乎非常方便。

If you can add the exception stack-trace along with your spring configuration that will help to answer more accurately. 如果您可以添加异常堆栈跟踪以及弹簧配置,这将有助于更准确地回答。 I am guessing it is because you might have more than one bean instances for NetworkUsageMapper class or its missing. 我猜这是因为您可能有多个用于NetworkUsageMapper类的bean实例或它缺少。

  1. If its missing just add one :). 如果它缺少只需添加一个:)。 To avoid exception you can use required attribute: 为避免异常,您可以使用required属性:

    @Autowired(required=false) private NetworkUsageMapper networkUsageMapper; @Autowired(required = false)私有的NetworkUsageMapper networkUsageMapper;

  2. If more than one then you need to use qualifier for example : 如果不止一个,那么你需要使用限定符,例如:

then 然后

@Autowired
@Qualifier("networkUsageMapper1")
private NetworkUsageMapper networkUsageMapper;

Hope it helps :Mak 希望它有所帮助:麦克

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM