Spring的autowire byType vs constructor(xml configuration)

时间:2018-01-28 08:07:28

标签: spring

我有一个查询。关于" Spring autowire byType vs constructor(xml configuration)"。

在多个地方读取构造函数autowire注入类似于byType。但是在我测试的时候,如果含糊不清,构造函数autowire的行为类似于 byName (甚至不完全正确),如果我遗漏了任何重要的一点,需要你的输入。

我的配置如下:

<bean name="customerRepository" class="repository.HibernameCustomerRepositoryImpl"/>
<bean name="customerRepository1" class="repository.EclipselinkCustomerRepositoryImpl"/>
<bean name="customerService" class="service.CustomerServiceImpl" autowire="..."/>

byType输出: org.springframework.beans.factory.NoUniqueBeanDefinitionException [Good Expected output]

constuctor输出: pankaj [注意我没有得到NoUniqueBeanDefinitionException,它为customerRepository提供输出原因?以下是示例代码] [似乎在模棱两可的情况下,它会检查属性名称并选择名称与属性名称匹配的bean]

示例代码:

public class CustomerServiceImpl implements CustomerService {

private CustomerRepository customerRepository;

public CustomerServiceImpl() {

}

public CustomerServiceImpl(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}

//  public void setCustomerRepository(CustomerRepository customerRepository) {
//  this.customerRepository = customerRepository;
//  }

@Override
public List<customer> findAll() {
return customerRepository.findAll();
}
}

2 个答案:

答案 0 :(得分:1)

是的,Spring确实可以按名称自动装配,但是不完全像“ byName”自动装配模式那样。

Spring Documentation的状态:

  

按属性名称自动装配。 Spring寻找与需要自动装配的属性同名的bean。例如,如果一个bean定义被设置为按名称自动装配,并且包含一个master属性(即,它具有setMaster(..)方法),那么Spring将查找一个名为master的bean定义,并使用它来设置该属性。

因此,为了通过名称自动接线,应该使用setter方法。但是,在这种情况下,容器将Bean定义名称与构造函数参数的名称匹配,以防歧义。

示例:

Motor.java

package com.chiranth;
public interface Motor 
{
    public void start();
}

ElectricMotor1.java

package com.chiranth;
public class ElectricMotor1 implements Motor
{
    public void start()
    {
        System.out.println("Motor 1 Started.");
    }
}

ElectricMotor2.java

package com.chiranth;
public class ElectricMotor2 implements Motor
{
    public void start()
    {
        System.out.println("Motor 2 Started.");
    }
}

TeslaModelX.java

package com.chiranth;
public class TeslaModelX 
{
    private Motor motor;

    public TeslaModelX(Motor electricMotor1)
    {
        motor=electricMotor1;
    }

    public void goForward()
    {
        motor.start();
        System.out.println("Going Forward.");
    }
}

Spring.xml

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="electricMotor1" class="com.chiranth.ElectricMotor1"/>
    <bean id="electricMotor2" class="com.chiranth.ElectricMotor2"/>

    <bean id="modelX" class="com.chiranth.TeslaModelX" autowire="constructor"/>
</beans>

Test.java

package com.chiranth;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test 
{
    public static void main(String[] args) 
    {
        ApplicationContext context= new ClassPathXmlApplicationContext("Spring.xml");
        TeslaModelX modelX=(TeslaModelX)context.getBean("modelX");
        modelX.goForward();
    }
}

输出:

Motor 1 Started.
Going Forward.

即使上面的示例中的属性名称与bean名称不匹配,也可以实现自动装配。

答案 1 :(得分:0)

是的,你是对的,当有一个模糊的情况时,Spring会按名称进行自动装配。您可以使用_localizer = (format, args) => {... }帮助Spring根据名称选择正确的实现 查看docs