Three implementations of @Autowired

@Autowired was introduced in Spring 2.5 and can be used for

1. Member variables

2. Method and

3. The constructor is annotated to complete the automatic assembly work. 

There is no need for traditional bean injection configuration in the bean's xml file. Instead, use annotations, which are automatically injected by the system for you, that is, implicit configuration.

First of all, you need to know : @Autowired is annotated according to type. If you need to assemble according to name, you need to use @Qualifier 
to specify the component that scans the package.

Example of use

Create a Spring configuration file

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
">
    <context:component-scan base-package="AutowiredTest"/>
    <bean id="cdPlayer" class="AutowiredTest.CDPlayer"/>
</beans

Write a test interface, here named CompactDisc

public interface CompactDisc {
    void play();
}

Use the annotation @Component to declare a component class. 
Implementation:

@Component
public class SgtPeppers implements CompactDisc{
    @Override
    public void play() {
        System.out.println("SgtPeppers    playing....");
    }
}

or on the constructor

public class CDPlayer {
    CompactDisc cd;   
    //对构造函数进行标注
    @Autowired
    public CDPlayer(CompactDisc cd){
        this.cd = cd;
    }
    public void say(){
        cd.play();
    }
}

Note: If the constructor has two parameters, bean1 and bean2, @Autowired will look for beans that match their types respectively

Write a test class to verify that CompactDisc is automatically injected for us.

public class Test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("AutowiredBean.xml");
        CDPlayer player = (CDPlayer) context.getBean("cdPlayer");
        player.say();
    }
}

Result:  SgtPeppers playing….

Run, the verification is successful, the system automatically injects the component class SgtPeppers for us. 
Due to interface programming, it is very likely that multiple classes implement the same interface. If Spring scans multiple matching objects, Spring does not know which one to choose, and Spring will report an error. . . To fix this, keep reading.

Assembly conflict problem

What happens if there is another OtherPeppers class that also implements the CompactDisc interface and is also annotated as a component class? 
Running found an error:

org.springframework.beans.factory.BeanCreationException:
 Error creating bean with name 'cdPlayer': 
 Injection of autowired dependencies failed; 
 nested exception is org.springframework.beans.factory.BeanCreationException:
 Could not autowire method: 
 public void AutowiredTest.CDPlayer.setCompactDisc(AutowiredTest.CompactDisc); 
 nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
 No qualifying bean of type [AutowiredTest.CompactDisc] is defined: 
 expected single matching bean but found 2: otherPeppers,sgtPeppers

There is an ambiguity problem in the above problem, and there are many ways to solve it.

1. Set the preferred Component and mark it with @Primary (if many places are marked, there will still be ambiguity problems);

2、限定自动装配的bean,在自动装配注解出添加注解@Qualifier(“name”),其中name为bean的ID(默认bean ID为类名首字母小写);如果重命名了组件类,那么自动装配将会失败。

3、通过自定义的限定符,其实就是在组件类与自动装配处,同时注解Qualifier(“name”),name为自定义且两出相同。

4、通过使用自定义的限定符注解,例如我用使用@Cold来标注组件类和自动装配两处。那么@Cold怎么自定义呢?我们需要自定义下该注解。

@Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy{}

拓展篇

1、@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。 
2、@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

@Autowired() @Qualifier("baseDao")     
private BaseDao baseDao;    

3、@Resource(这个注解属于J2EE的),默认安照名称进行装配,名称可以通过name属性进行指定, 
如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配,如下所示。

@Resource(name="baseDao")     
private BaseDao baseDao;    

用 @Resource注解在字段上,且这个注解是属于J2EE的,减少了与spring的耦合。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326477173&siteId=291194637