Spring中Bean对象的装配/注入(属性注入、构造方法注入、Setter注入)、@Autowired与@Resource的对比、如何解决同一类型多个bean的报错问题

目录

Bean对象注入

属性注入

构造方法注入 

Setter注入 

三种注入方式优缺点

@Resource注解 

@Autowired与@Resource的区别 

同一类型多个Bean问题的解决 


Bean对象注入

也就是DI(依赖注入):将某个对象需要的依赖注入到属性中,常见的对象注入方法有属性注入、构造方法注入、Setter注入

属性注入

属性注入是通过@Autowired注解实现的,将Service类注入到Controller类中

代码示例

User类

package org.example.model;
import lombok.Data;
@Data
public class User {
    private String userName;
    private Integer id;
}

Service类 

模拟根据id获取用户信息的操作

package org.example.service;
import org.example.model.User;
import org.springframework.stereotype.Service;
@Service
public class UserService {
    public User getUser(Integer id) {
        User user = new User();
        user.setId(id);
        user.setUserName("Java-" + id);
        return user;
    }
}

Controller类

通过@Autowired注解将容器中的bean对象注入到属性

package org.example.controller;
import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
    //属性注入
    @Autowired
    private UserService userService;

    public User getUser(Integer id) {
        return userService.getUser(id);
    }
}

启动类

public class APP {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("org.example");
        UserController userController = context.getBean(UserController.class);
        System.out.println(userController.getUser(1));
    }
}

 

构造方法注入 

构造方法注入是在类的构造方法中实现注入

package org.example.controller;
import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController2 {
    private UserService userService;

    @Autowired
    public UserController2(UserService userService) {
        this.userService = userService;
    }
//    public UserController2() {
//        
//    }
    public User getUser(Integer id) {
        return userService.getUser(id);
    }
}

User类、Service类以及启动类都与上述类似,此时就成功通过构造方法注入Bean对象。当Controller类中只有一个构造方法时,可以省略@Autowired注解,如果有多个构造方法,就必须添加上@Autowired来指定具体是使用哪个构造方法,否则就会出现如下报错

 

Setter注入 

Setter注入和属性的Setter方法实现类似,只不过在设置set方法的时候需要加上@Autowired注解

package org.example.controller;

import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController3 {
    //Setter注入
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public User getUser(Integer id) {
        return userService.getUser(id);
    }
}

注意:使用构造方法进行属性注入时,当类中只有一个构造方法时可以省略@Autowired注解,但是使用Setter进行属性构造时,不能省去@Autwired注解

三种注入方式优缺点

· 属性注入的优点是简洁,使用方便;缺点是只能用于IoC容器,如果是非IoC容器不可用,并且在使用时会出现空指针异常

· 构造方法注入是Spring推荐的注入方式,他的缺点是如果多个注入会显得比较臃肿,但出现这种情况应该考虑一下是否符合程序的单一职责的设计模式,它的优点是通用性,在使用之前一定要保证注入的类不为空

· Setter 方式是 Spring 前期版本推荐的注入方式,但通用性不如构造方法,所有 Spring 现版本已经推荐使用构造方法注入的方式来进行类注入了。

@Resource注解 

在进行类注入时除了使用@Autowired外还可以使用@Resource进行注入

package org.example.controller;
import org.example.model.User;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;
@Controller
public class UserController {
    //属性注入
    //@Autowired
    @Resource
    private UserService userService;

    public User getUser(Integer id) {
        return userService.getUser(id);
    }
}

@Autowired与@Resource的区别 

· @Autowired是Spring的注解,而@Resource收JDK的注解

· 使用时设置的参数不同,相比于@Autowired,@Resource支持更多的参数设置,例如name设置,设置之后就可以根据name的值来获取Bean

同一类型多个Bean问题的解决 

@Configuration
public class AppConfig {
    //方法上使用Bean注解表示注册一个Bean对象到容器中
    //方法的名称,就是bean ID(名称),方法的返回值就是注册的实例对象
    //一般是public修饰的实例方法
    @Bean
    public User testBean1() {
        User user = new User();
        user.setUserName("testBean1");
        return user;
    }

    @Bean
    public User testBean2() {
        User user = new User();
        user.setUserName("testBean1");
        return user;
    }
}
@Controller
public class UserController {
    @Autowired
    private User user;
}

 当遇到上述问题时,有三种解决方式

①变量名=bean的id(名称)

@Controller
public class UserController {
    @Autowired
    private User testBean1;
}

②使用@Resource(name="xxx")

@Controller
public class UserController {
    @Resource(name = "testBean1")
    private User user;
}

 ③使用@Qualifier

@Controller
public class UserController {
    @Autowired
    @Qualifier("testBean2")
    private User user1;
}

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Li_yizYa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值