【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别

文章目录

  • 1. 对象注入
    • 1.2 属性注入
      • 1.2.1 属性注入的优缺点
    • 1.3 Setter方法注入
      • 1.3.1 Setter注入的优缺点
    • 1.4 构造方法注入(官方推荐)
      • 1.4.1 构造方法的优缺点
    • 1.5 @Resource与@Autowired区别

1. 对象注入

获取Bean对象也称为对象注入/对象装配,表示把某个对象从Spring容器中取出来给某个类。

对象注入的方法有三种:

  1. 属性注入
  2. Setter注入
  3. 构造方法注入

1.2 属性注入

属性注入是用一个叫@Autowired注解实现的,当spring运行时,会将实现@Autowired注解的属性自动获取一个对象。

下述代码展示:将Service类注入到Controller类中。

  • Service代码:
import org.springframework.stereotype.Service;

@Service
public class UserService {
	 /**
     *     注意:此处是伪代码,用来代替数据库 实际中是不用new对象的
     * @param id 根据Id获取用户信息
     * @return 返回一个对象存储到Spring容器中
     */
    public User getUser(Integer id){
        User user = new User();
        user.setName("lisi");
        user.setAge(18);
        user.setId(1);
        return user;
    }
}
  • Controller代码:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
	//使用注解 自动获取spring容器中的Bean对象/对象注入
    @Autowired
    private UserService userService;
    
    public User getUser(Integer id){
        return userService.getUser(id);
    }
}

在Controller类中使用@Autowired注解时,对象引用名建议首字母小写,合规;因为在获取对象时是按照UserService这个类搜索,再按照userService这个名字获取的,这个命名规则是spring规定的;

  • 测试是否拿到了Service类:成功拿到了
public class App {
    public static void main(String[] args) {
        //1.得到spring
        ApplicationContext context =
                 new ClassPathXmlApplicationContext("spring-config.xml");
        //2.获得bean
        UserController userController  = context.getBean("userController",UserController.class);
        //验证是否获取到Bean对象
        System.out.println(userController.getUser(1).toString());
    }
}

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第1张图片

1.2.1 属性注入的优缺点

优点:简单粗暴

缺点:

  1. 没办法实现final修饰的变量注入。
  2. 兼容性差,只适用于IoC容器
  3. 由于使用简单,更容易违反单一设计原则(单一设计原则:一个类一个功能)

1.3 Setter方法注入

Service类代码和测试类代码不变,变更Controller代码:

@Controller
public class UserController {

    private UserService userService;

    /*
    	在set方法上添加@Autowired注解,spring容器会自动把Bean对象传过来
    */
    @Autowired
    public void setUserService(UserService userService){
        this.userService = userService;
    }
    public User getUser(Integer id){
        return userService.getUser(id);
    }
}

  • 调用测试类验证:

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第2张图片

1.3.1 Setter注入的优缺点

优点:由于set方法只会传入一个参数,所以更符合单一设计原则

缺点:

  1. 不能注入final不可变对象
  2. 使用Setter注入的对象可能会被修改;因为在set方法进行注入后,可以在任何地方new一个UserController对象调用setUserService修改userService的引用。

1.4 构造方法注入(官方推荐)

Service类代码和测试类代码不变,变更Controller代码:

@Controller
public class UserController {

    private UserService userService;
    /*
        当只有一个构造方法时,可以省略@Autowired
        一样可以完成对象注入
     */
    public UserController(UserService userService) {
        this.userService = userService;
    }
}

当只有一个构造方法时,可以省略@Autowired,但是有多个构造方法时不能省略@Autowired。

  • 调用测试类:

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第3张图片

为什么构造方法可以省略注解?那是因为这是官方推荐的,自然要大力支持啦。就好像HashMap与HashTable,HashMap可以允许key-value是null,但是HashTable就不能,因为HashTable底层可能是数组加链表实现的,需要根据key值来计算位置的,HashMap源码中写了null值的处理,为null转换成0,而HashTable并没有进行特别处理,只能报错。

1.4.1 构造方法的优缺点

优点:

  1. 可以注入final不可变对象(因为被final修饰的对象的初始化要么在定义时进行赋值,要么在构造方法中赋值
  2. 注入的对象不会被改变(构造方法只能执行一次)
  3. 构造方法可以保证注入的对象完全被初始化(在类加载的初始化阶段就会执行构造方法,之后再把类注入到spring容器中)
  4. 兼容性好(构造方法是所有框架都支持的)

缺点:无

1.5 @Resource与@Autowired区别

使用@Resource注解进行对象注入,可以看到@Resource注解不能用于构造方法上。

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第4张图片

  • 使用@Resource注解成功获取对象:

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第5张图片

@Resource与@Autowired区别:

  1. @Resource是来自JDK,@Autowired来自spring官方

  2. @Resource的注入能力弱于@Autowired,只能用于属性注入和set方法注入,@Autowired可以用于属性注入、set方法注入以及构造方法注入

  3. @Resource提供的参数更多,@Autowired只有一个required参数,这就导致如果同一个类 被注入多个到spring容器中,使用@Autowired就不行,使用@Resource的来设置name属性。
    4.查询Bean顺序不同:@Resource先根据名称查询,再根据类名查询,@Autowired先根据类名查询,再根据名称查询。

  • @Resource提供的参数:

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第6张图片

  • @Autowired提供的参数:

@Autowired只有一个required参数,这就导致如果同一个类被重复注入到spring容器中,使用@Autowired就不行,必须使用@Resource的来设置name属性,区分Bean对象。当然也可以使用@Autowired搭配@Qualifier(name = “”)实现区分Bean对象

  • @Resource提供的参数:

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第7张图片

  • @Autowired提供的参数:

【Spring】三种对象注入的实现与区别以及@Autowired和@Resource的区别_第8张图片

你可能感兴趣的:(JavaEE,java,开发语言,spring)