spring注解驱动开发(六):spring自动装配详解@Autowired、@Source、@Inject

自动装配:

    Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系的赋值。

    自动装配有三个注解,分别是@Autowired(spring注解)、@Source(JSR250注解)、@Inject(JSR330注解),在实际的使用中,经常使用这三种注解,下面通过代码的方式来详细介绍三种不同的注解。

1 @Autowired、@Qualifier、@Primary注解

    @Autowired:根据类型自动装配,如果容器中相同类型的组件就一个,可以完成所有自动装配功能。

    @Qualifier:是对@Autowired注解的补充使用,可以准确使用的bean。

    @Primary:如果容器中相同类型的组件有多个,使用这个注解指定有限使用的组件。

1.1 @Autoeired基本使用代码示例

    1) 定义三个类,分别是UserController、UserService和UserDao,分别使用相关注解将组件放到容器中

@Controller
public class UserController {
    
}

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public String toString() {
        return "UserService{" +
                "userDao=" + userDao +
                '}';
    }
}

@Repository
public class UserDao {

    private int lable=1;

    public int getLable() {
        return lable;
    }

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

    @Override
    public String toString() {
        return "UserDao{" +
                "lable=" + lable +
                '}';
    }
}

    2) 新建配置类,配置好包扫描

@Configuration
@ComponentScan("org.gwsix.ch06")
public class MainConfigAutowired06 {

    @Bean("userDao2")
    public UserDao userDao(){
        UserDao userDao = new UserDao();
        userDao.setLable(2);
        return  userDao;
    }
}

    3) 新建测试类,添加测试方法

public class Main {

    @Test
    public void testAutowired() {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigAutowired06.class);
        System.out.println(applicationContext.getBean("userDao"));
        System.out.println(applicationContext.getBean("userService"));
    }
}

    4) 控制台输出

UserDao{lable=1}
UserService{userDao=UserDao{lable=1}}

    小结:通过控制台的输出,可以得到Uservice中使用的bean和容器中的bean是统一个,说明@Autowired自动装配成功。

    现在又一个需求,在要求在UserService不使用userDao而使用userDao2,可以有两种操作第一种在UserService在引入UserDao时明确指定名

        1)private UserDao userDao2;指定属性名,@Autowired默认时根据类型装配,如果相同类型存在多个则使用属性名装配。

        2) 使用@Qualifier("userDao2") 在属性名上,@Qualifier注解在不修改原有代码的情况下,会让sprig来精确自动装配("beanName")里面的beanName。

1.2 @Primary基本使用代码

    如果在容器中相同类型存在多个bean,但想让其中某一个bean作为默认的bean,在不特殊指定(使用@Qualifier注解精确指定),使用默认的Bean使用,可以用Spring中的@Primary注解。

    @Primary注解的作用是在不明确指定bean时,作为相同类型的默认bean自动装配。

    使用:可以在@Bean,@Repository和其他使组件注入到容器的注解上使用,目的是让类作为相同类型的默认类。

1.3 @Autowired bean不存在的情况

    Spring在使用@Autowired注解的时候,默认要求装配的组件必须在容器中,不然会抛出异常,可以使用@Autowird(require = false)属性来指定,使用require=false后如果使用的bean不存在则会注入一个null,这样不会造在注入时候异常。

2 @Resource注解(JSR250)

    @Resource是Java中JSR250的规范。JSR(Java Specification Requests):Java 规范提案。

    @Resource注解和@Autowired注解对比。

    @Resource注解可以在部分环境中替换@Autowired,本身自带@Qualifier注解功能,可以精确指定容器中bean

    @Resource注解不能和@Primary注解配合只用,说明@Resource不能指定多类型下默认使用的bean;同时缺少require=false,如果容器中缺少装配的bean会抛出异常。

3 @Inject注解(JSR330)

    @Inject拥有@Autowird注解的大部分功能,可以精确指定注入bean的名称,可以配合@Primary注解使用来指定 

    @Inject没有指定require=false,容器缺少bean在自动装配抛出异常。使用@Inject需要导入依赖。

<!-- https://mvnrepository.com/artifact/javax.inject/javax.inject -->
<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

4 @Autowired、@Resource和@Inject注解对比

  @Autowired @Resource @Inject
可以精确指定装配的bean 需要和@Qualifier注解配合使用 可以,注解括号内指定bean 可以,注解括号内指定bean
配合@Primary指定默认bean 可以 不可以 可以
在bean不存在能否正常装配 可以,需要指定required=false 不可以 不可以

5 @Autowired可使用的位置

    @Autowired除了标注在属性上还可以放在其他位置

    1. 标注在属性上

    2.get、set方法上,一般放在set方法方法上

    3.构造器【如果bean只有一个有参构造器可以省略,参数默认从容器中获得】

    4.参数位置【@Bean+方法参数,参数可以不用@Autowired,默认从容器中获得】

posted @ 2019-03-26 10:15  i孤独行者  阅读(1622)  评论(0)    收藏  举报