Spring注解驱动第十讲--@Autowired使用

概念理解:

  自动装配:Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;

一.可以利用@Autowired注解实现自动注入,这里省去了一些简单bean的创建,示例代码如下:

BookService.java

@Service
public class BookService {
    @Autowired
    private BookDao bookdao;

    @Override
    public String toString() {
        return "BookService [bookdao=" + bookdao + "]";
    }
}

BookDao.java

@Repository
public class BookDao {

}

测试方法:

    @Test
    public void test02() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigAutoware.class);
        BookService bookService = applicationContext.getBean(BookService.class) ;
        System.out.println(bookService);//打印出BookService中的BookDao对象
        BookDao bookDao = applicationContext.getBean(BookDao.class);
        System.out.println(bookDao);//打印出容器中的BookDao对象

     applicationContext.close(); //关闭容器
}

运行结果

BookService [bookdao=com.dao.BookDao@75f9eccc]
com.dao.BookDao@75f9eccc

  从上面的运行结果可以看出:容器中的bean和自动注入到BookService中的bean是统一个BookDao@75f9eccc.@AutoWired注解的工作原理就是,如果某个类中引用容器中的bean,可以在该类的该属性上加@Autowired注解即可.

那么@AutoWired默认优先按照类型去容器中找对应的组件.

  此种情况是容器中只有一个bean对象的时候,如果找到多个相同类型的组件,那么Spring将会抛出一个错误

    expected single matching bean but found 2: bookDao,bookDao2

  对于这种找到多个Bean对象的时候,可以使用@Qualifier("指定的id名字"),来指定具体使用哪个bean实例代码如下:

@Service
public class BookService {
    @Qualifier("bookDao")//指定加载"bookDao"
    @Autowired
    private BookDao bookdao;
    @Override
    public String toString() {
        return "BookService [bookdao=" + bookdao + "]";
    }
}

此时,错误将会消失;容器中会加载bookDao对象;

另一种解决办法就是使用@Primary注解,该注解加载配置类的@Bean注解下,意为当存在两个相同类型的bean时,取被@Primary标注的bean对象

配置类代码如下:

@Configuration
@ComponentScan({"com.wxj.service","com.wxj.dao"})
public class MainConfigAutoware {
    @Primary
    @Bean("bookDao2")
    public BookDao bookDao() {
        BookDao bookDao = new BookDao() ;
        bookDao.setLable("2");
        return bookDao ;
    }
}

更改BookDao类

@Repository
public class BookDao {
    private String lable = "1";

    public String getLable() {
        return lable;
    }

    public void setLable(String lable) {
        this.lable = lable;
    }

    @Override
    public String toString() {
        return "BookDao [lable=" + lable + "]";
    }
}

运行测试结果:

BookService [bookdao=BookDao [lable=2]]

容器中加载的是被@Primary标注的bean.

注意:如果@Qualifier和@Primary注解同时使用,首选@Qualifier指定的bean;

还有一种情况就是,容器中没有该类型的bean,运行测试类将会报错:

expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

根据Spring容器的提示可以看到,类中若使用@AutoWired注解实现自动装配,那么在容器中就至少有一个该类型的bean.那么若何解决该问题呢?可以通过指定@Autowired的required属性来说明该对象有就加载,没有就不加载

@Autowired(required=true):默认的情况,说明容器中必须存在被@Autowired注解的bean,

@Autowired(required=false):说明容器中有指定的bean就加载,没有就不加载.

扩展:@Autowired还可以加在其他位置;

  1,方法上:Spring容器创建当前对象,就会调用方法完成赋值.方法使用的参数就是从ioc容器中进行获取

  2,有参构造器:在容器创建bean对象时,也会从容器中进行选取.如果容器中只有一个有残构造器,注解还可以省略掉.

  3,参数的位置:也是从容器中获取,@Bean标注的对象创建对象时方法的参数值也是从容器中获取.

二,@Resource(JSR250):可以和@Autowired一样实现自动装配.默认是按照组件的id进行装备,不支持@Primary和required属性.也不能和@Qualifier组合使用

三,@Inject(JSR330):需要导入javax.inject的包,和@Autowired一样的使用方法但是没有任何属性

扩展,以上注解的工作原理主要是依赖AutowiredAnnotationBeanPostProcessor类进行实现

原文地址:https://www.cnblogs.com/xingjia/p/11250148.html