当前位置: 首页 > article >正文

Spring中存储Bean的常见注解

目录

IoC & DI

IOC(控制反转)详解

依赖注入的三种方式


IoC & DI

IoC: Inversion of Control (控制反转), 也就是说 Spring 是⼀个"控制反转"的容器.

控制反转:也就是控制权反转. 什么的控制权发⽣了反转? 获得依赖对象的过程被反转了
也就是说, 当需要某个对象时, 传统开发模式中需要⾃⼰通过 new 创建对象, 现在不需要再进⾏创
建, 把创建对象的任务交给容器
, 程序中只需要依赖注⼊ (Dependency Injection,DI)就可以了.
这个容器称为:IoC容器. Spring是⼀个IoC容器, 所以有时Spring 也称为Spring 容器。

DI: Dependency Injection(依赖注⼊)
容器在运⾏期间, 动态的为应⽤程序提供运⾏时所依赖的资源,称之为依赖注⼊

依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过
引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦。


IOC(控制反转)详解

共有两类注解类型可以实现Bean的存储:
1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration.
2. ⽅法注解:@Bean.

类注解

1、@Controller(控制器存储)

使⽤ @Controller 存储 bean 的代码如下所⽰: 

@Controller // 将对象存储到 Spring 中
public class UserController {
  public void sayHi(){
       System.out.println("hi,UserController...");
      }
}

表示将这个类的对象存储到ioc容器当中,并表明这是一个controller类。负责 接收请求, 对请求进⾏处理, 并进⾏响应。

2、@Service(服务存储)

使⽤ @Service 存储 bean 的代码如下所⽰:

@Service
public class UserService {
   public void sayHi(String name) {
       System.out.println("Hi," + name);
    }
}

表示将这个类的对象存储到ioc容器当中,并表明这是一个service类。负责处理具体的业务逻辑。

3、@Repository(仓库存储)

使⽤ @Repository 存储 bean 的代码如下所⽰:

@Repository
public class UserRepository {
  public void sayHi() {
    System.out.println("Hi, UserRepository~");
   }
}

表示数据访问层,也称为持久层. 负责数据访问操作

4、@Component(组件存储)

使⽤ @Component 存储 bean 的代码如下所⽰:

@Component
public class UserComponent {
  public void sayHi() {
     System.out.println("Hi, UserComponent~");
   }
}

 单纯将这个类的对象加入到ioc容器中,没有其他含义。

5、@Configuration(配置存储)

使⽤ @Configuration 存储 bean 的代码如下所⽰:

@Configuration
public class UserConfiguration {
  public void sayHi() {
    System.out.println("Hi,UserConfiguration~");
   }
}

表示配置层. 处理项⽬中的⼀些配置信息。

方法注解

@Bean

@Bean注解可以将类中的方法注入到ioc容器当中,使一个类可以拥有多个对象。

使用@Bean注解存储bean代码如下:

@Component
public class BeanConfig {
   @Bean
   public User user(){
      User user = new User();
      user.setName("zhangsan");
      user.setAge(18);
      return user;
    }
}

@Bean注解必须搭配@Component注解使用才能生效。否则无效。

@Bean注解的优势在于同一个类可以定义多个对象

@Component
public class BeanConfig {
  @Bean
  public User user1(){
    User user = new User();
    user.setName("zhangsan");
    user.setAge(18);
    return user;
  }
  @Bean
  public User user2(){
    User user = new User();
    user.setName("lisi");
    user.setAge(19);
    return user;
  }
}

类中的两个Bean对象的名称如下: 

可以通过设置 name 属性给 Bean 对象进⾏重命名操作,如下代码所⽰:

@Bean(name = {"u1","user1"})
public User user1(){
    User user = new User();
    user.setName("zhangsan");
    user.setAge(18);
    return user;
}

 依赖注入的三种方式

关于依赖注⼊, Spring给我们提供了三种⽅式:

1. 属性注⼊(Field Injection)

属性注⼊是使⽤ @Autowired 实现的,如将 Service 类注⼊到 Controller 类中.

Service 类的实现代码如下:

@Service
public class UserService {
   public void sayHi() {
     System.out.println("Hi,UserService");
  }
}

Controller 类的实现代码如下:

@Controller
public class UserController {
   //注⼊⽅法1: 属性注⼊
@Autowired
private UserService userService;
   public void sayHi(){
      System.out.println("hi,UserController...");
      userService.sayHi();
   }
}

最终结果如下:


2. 构造方法注⼊(Constructor Injection)

构造⽅法注⼊是在类的构造⽅法中实现注⼊,如下代码所示:

@Controller
public class UserController2 {
//注⼊⽅法2: 构造⽅法
  private UserService userService;
  @Autowired
  public UserController2(UserService userService) {
     this.userService = userService;
  }
  public void sayHi(){
    System.out.println("hi,UserController2...");
    userService.sayHi();
  }
}

注意事项:如果类只有⼀个构造⽅法,那么 @Autowired 注解可以省略;如果类中有多个构造⽅法,那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法。

3. Setter 注⼊(Setter Injection)

Setter 注⼊和属性的 Setter ⽅法实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注
解 ,如下代码所⽰:

@Controller
public class UserController3 {
//注⼊⽅法3: Setter⽅法注⼊
private UserService userService;
  @Autowired
  public void setUserService(UserService userService) {
     this.userService = userService;
  }
  public void sayHi(){
     System.out.println("hi,UserController3...");
     userService.sayHi();
  }
}

 特殊情况:当同一类型存在多个bean对象时,使用@Autowired会出现问题。

@Component
public class BeanConfig {
  @Bean("u1")
  public User user1(){
    User user = new User();
    user.setName("zhangsan");
    user.setAge(18);
    return user;
  }
  @Bean
  public User user2() {
    User user = new User();
    user.setName("lisi");
    user.setAge(19);
    return user;
  }
}
@Controller
public class UserController {
@Autowired
private UserService userService;
//注⼊user
@Autowired
private User user;
  public void sayHi(){
    System.out.println("hi,UserController...");
    userService.sayHi();
    System.out.println(user);
  }
}

spring提供了以下解决方案:

@Primary

使⽤@Primary注解:当存在多个相同类型的Bean注⼊时,加上@Primary注解,来确定默认的实现.

@Component
public class BeanConfig {
@Primary //指定该bean为默认bean的实现
  @Bean("u1")
  public User user1(){
    User user = new User();
    user.setName("zhangsan");
    user.setAge(18);
    return user;
  }
  @Bean
  public User user2() {
    User user = new User();
    user.setName("lisi");
    user.setAge(19);
    return user;
  }
}

 @Qualifier

使⽤@Qualifier注解:指定当前要注⼊的bean对象。 在@Qualifier的value属性中,指定注⼊的bean的名称。
• @Qualifier注解不能单独使⽤,必须配合@Autowired使⽤

@Controller
public class UserController {
@Qualifier("user2") //指定bean名称
@Autowired
private User user;
  public void sayHi(){
    System.out.println("hi,UserController...");
    System.out.println(user);
  }
}

 @Resource

使⽤@Resource注解:是按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称。

@Controller
public class UserController {
@Resource(name = "user2")
private User user;
  public void sayHi(){
     System.out.println("hi,UserController...");
     System.out.println(user);
  }
}

常⻅⾯试题:
@Autowird 与 @Resource的区别
• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐于 @Autowired 来说,
@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。

以上关于IOC与DI,希望对你有所帮助。


http://www.kler.cn/a/310971.html

相关文章:

  • HTTP常见的请求头有哪些?都有什么作用?在 Web 应用中使用这些请求头?
  • js 获取某日期到现在的时长 js 数字补齐2位
  • 结构体是否包含特定类型的成员变量
  • [代码随想录Day10打卡] 理论基础 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项
  • Kafka - 启用安全通信和认证机制_SSL + SASL
  • Prometheus面试内容整理-Prometheus 的架构和工作原理
  • python的数据类型详解
  • MyBatis系统学习(三)——动态SQL
  • 简单题28-找出字符传中第一个匹配项的下标(Java and Python)20240918
  • ElasticSearch介绍+使用
  • 3. Python计算水仙花数
  • 利士策分享,赚钱与体重:一场关于生活平衡的微妙探索
  • 云计算服务的底层,虚拟化技术的实现原理
  • 假期学习--iOS 编译链接
  • 如何挑选一款性价比高的开放式耳机?高性价比宝藏蓝牙耳机推荐
  • 吸浮毛宠物空气净化器推荐,希喂、小米、有哈宠物空气净化器测评
  • 句子成分——每日一划(八)
  • 算法:30.串联所有单词的子串
  • 【MySQL】SQL语句的优化
  • Keil MDK5学习记录
  • 自定义Spring Security认证处理的完整解决方案
  • 2024ICPC第一场网络赛补题
  • 思通数科开源智能文档识别平台的核心功能
  • 在Linux服务器上如何实现自动化部署?
  • 【车载以太网】【SOME/IP】Wireshark 解析
  • Maven 的多种打jar包方式详细介绍、区别及使用教程——附使用命令