定制小程序开发Spring(存储Bean对象五大类注解,获取Bean对象三种注入方式)

目录


定制小程序开发在上一篇中,可以看到,创建Spring需要三步,存 bean 需要三步, 取 bean 需要三步,定制小程序开发感觉这个读取和存储对定制小程序开发象的步骤并没有想象的那么 "简单" 啊

定制小程序开发所以本篇将学习通过 "使用注解" 定制小程序开发来更简单的存储和读取对象


定制小程序开发前面在存储 Bean 时,需要在 spring-config 定制小程序开发中添加一行 bean 注册内容,这个XML定制小程序开发文件有一点不好的是调试,而且XML定制小程序开发文件报错了是不影响项目运行的,定制小程序开发即使报错了,也可能发现不了.

1. 先进行配置扫描路径

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:content="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
  6. <content:component-scan base-package="com.bit.service"></content:component-scan>
  7. </beans>

在 spring 配置文件中设置 bean 的扫描根路径


2. 存储 Bean 对象 ( 添加注解存储 Bean 对象)

使用 5 大类注解实现,就不用在spring-config 中添加一行 bean 注册内容了

2.1 @Controller [控制器存储]

  1. package com.beans;
  2. import org.springframework.stereotype.Controller;
  3. @Controller
  4. public class UserController {
  5. public void sayHi() {
  6. System.out.println("你好,UserController!");
  7. }
  8. }
  1. import com.beans.UserController;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class app {
  5. public static void main(String[] args) {
  6. //1. 先得到上下文对象
  7. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  8. //2. 得到 bean
  9. UserController controller = context.getBean("userController",UserController.class);
  10. //3. 使用 bean
  11. controller.sayHi();
  12. }
  13. }

2.2 @Service [服务存储]

  1. import com.beans.UserController;
  2. import com.beans.UserService;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. public class app {
  6. public static void main(String[] args) {
  7. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  8. UserService service = context.getBean("userService",UserService.class);
  9. service.sayHi();
  10. }
  11. }
  1. package com.beans;
  2. import org.springframework.stereotype.Service;
  3. @Service
  4. public class UserService {
  5. public void sayHi() {
  6. System.out.println("你好,Service!");
  7. }
  8. }

2.3 @Repository [仓库存储]

  1. import com.beans.UserRepository;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class app {
  5. public static void main(String[] args) {
  6. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  7. UserRepository repository = context.getBean("userRepository",UserRepository.class);
  8. repository.sayHi();
  9. }
  10. }
  1. package com.beans;
  2. import org.springframework.stereotype.Repository;
  3. @Repository
  4. public class UserRepository {
  5. public void sayHi() {
  6. System.out.println("你好,Repository!");
  7. }
  8. }

2.4 @Configuration [配置存储]

  1. package com.beans;
  2. import org.springframework.context.annotation.Configuration;
  3. @Configuration
  4. public class UserConfiguration {
  5. public void sayHi() {
  6. System.out.println("你好,Configuration!");
  7. }
  8. }
  1. import com.beans.UserConfiguration;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class app {
  5. public static void main(String[] args) {
  6. //1. 先得到上下文对象
  7. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); UserConfiguration configuration = context.getBean("userConfiguration",UserConfiguration.class);
  8. configuration.sayHi();
  9. }
  10. }

2.5 @Component [组件存储]

  1. package com.beans;
  2. import org.springframework.stereotype.Component;
  3. @Component
  4. public class UserComponent {
  5. public void sayHi() {
  6. System.out.println("你好,Component!");
  7. }
  8. }
  1. import com.beans.*;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class app {
  5. public static void main(String[] args) {
  6. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  7. UserComponent component = context.getBean("userComponent",UserComponent.class);
  8. component.sayHi();
  9. }
  10. }

2.6 五大类注解的作用和关系

(1) 作用:

这么多注解的作用是,如果一个项目特别大的情况下,文件会非常杂乱的,所以就是通过注解,来让程序员看到注解后就知道了,当前类的作用

程序的最基础⼯程分层,调⽤流程如下

 (2) 关系:

在五大注解类中 Component 可以当做其他注解的父类

其他类之间的关系可以当做是兄弟

下面看一下源码

2.7 Bean的命名规则

在前按照规范"大驼峰"取类名,然后getBean按照规范"小驼峰"是可以运行成功的

 而写如果写一个这样的类

 但是如果,这样写就可以运行成功

 那么 Bean 的命名规则到底应该是什么样的

所以根据这个规则,正常下命名,如果类的前两个字符都为大写字母,就写原名字

如果只有第一个字母为大写,那就按"小驼峰" 来命名


2.8 使用方法注解 @Bean

@Bean 是加在方法上的,并且只使用一个 @Bean 是无法将对象存储到容器中的,所以还要给类加个注解

Bean 就是类注解的基础上缩小范围

  1. package com.beans;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. public class UserBeans {
  6. @Bean //[只使用一个 @Bean 是无法将对象存储到容器中]
  7. public User user1() {
  8. User user = new User();
  9. user.setId(1);
  10. user.setName("张三");
  11. return user;
  12. }
  13. }
  1. import com.beans.*;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class app {
  5. public static void main(String[] args) {
  6. //1. 先得到上下文对象
  7. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  8. User user = context.getBean("user1",User.class);
  9. // User user = context.getBean(User.class);
  10. System.out.println(user);
  11. }
  12. }
  1. package com.beans;
  2. public class User {
  3. private int id;
  4. private String name;
  5. @Override
  6. public String toString() {
  7. return "User{" +
  8. "id=" + id +
  9. ", name='" + name + '\'' +
  10. '}';
  11. }
  12. public int getId() {
  13. return id;
  14. }
  15. public void setId(int id) {
  16. this.id = id;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. }

2.8.1 重命名 Bean

可以通过设置 name 属性给 Bean 对象进⾏重命名操作

  1. package com.beans;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. public class UserBeans {
  6. @Bean(name = "userinfo") //[只使用一个 @Bean 是无法将对象存储到容器中]
  7. public User user1() {
  8. User user = new User();
  9. user.setId(1);
  10. user.setName("张三");
  11. return user;
  12. }
  13. }

@Bean 命名规则,当没有设置name属性时,那么 bean 默认的名称就是方法名,

当设置name属性后,只能通过重命名的name属性对应的值来获取,也就是说再使用方法就获取不到 bean 对象了,

并且也可以 一个bean 有多个名字,像数组一样在{}中写上多个名字,就可以了 


3. 获取 Bean 对象 (对象装配) 

获取 Bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入

3.1 属性注入

通过 @Autowired 就可以属性注入

  1. package com.beans;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Controller;
  4. @Controller
  5. public class UserController2 {
  6. // 对象注入1: 属性注入
  7. @Autowired
  8. private UserService userService;
  9. public void sayHi() {
  10. userService.sayHi();
  11. }
  12. }
  1. import com.beans.*;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class app {
  5. public static void main(String[] args) {
  6. //1. 先得到上下文对象
  7. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  8. UserController2 controller2 = context.getBean(UserController2.class);
  9. controller2.sayHi();
  10. }
  11. }

3.2 构造方法注入

写构造方法,参数传入要注入的对象,然后写上注解 @AutoWired (如果当前类中只有一个构造方法,那就可以省略注解)

  1. package com.beans;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Controller;
  4. @Controller
  5. public class UserController2 {
  6. //使用构造方法实现 bean 注入(官方推荐写法)
  7. private UserService userService;
  8. @Autowired
  9. public UserController2(UserService userService) {
  10. // userService = new UserService(); //传统的写法
  11. this.userService = userService;
  12. }
  13. public void saHi() {
  14. userService.sayHi();
  15. }
  16. }

3.3 Setter注入

Setter 注入,写要注入的属性的 setter方法,然后加上注解 @Autowired

  1. package com.beans;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Controller;
  4. @Controller
  5. public class UserController2 {
  6. //3. 使用 Setter 注入
  7. private UserService userService;
  8. @Autowired
  9. public void setUserService(UserService userService) {
  10. this.userService = userService;
  11. }
  12. public void sayHi() {
  13. userService.sayHi();
  14. }
  15. }

3.4 面试题: 三种注入优缺点分析

属性注入 / 构造方法注入 / Setter注入

  1. 属性注入特点: 写法简单,只适用于 IoC容器,通用性不好
  2. 构造方法注入: 这种写法从 spring 3.4后就成推荐写法了,通用性更好,能确保在使用注入对象之前,此注入对象一定是初始化过的.当构造方法注入参数过多时,开发者就要检查自己所写的代码是否符合单一设计原则的规范了.
  3. Setter 注入特点:这种写法是早期 Spring 版本的推荐写法(大概是3.4前),Setter 注入通用性没有构造方法注入通用

3.5 @Resource:另一种注入关键字

@Resource: 支持 属性注入 和 Setter 注入,但不支持构造方法注入

面试题: @Autowired 和 @Resource 的区别

相同点: 都可以实现将一个对象注入到类中
不同点:
  1. 出身不同: @Resource 来自 JDK ;    @Autowired 是 Spring 框架提供的
  2. 用法不同: @Resource 用于 属性注入/Setter 注入 ;  @ Autowired 用于 属性注入/构造方法注入/Setter注入
  3. 支持的参数不同: @Resource 支持更多的参数设置,name/type....  ;  而 @Autowired 只支持 required 参数设置

3.6 @Bean 将一个类型的对象注入多次的问题:

  解决方法

(1) 精确的描述 bean 的名称 (将注入的名称写对)

(2) 使用 @Resource 设置 name 的方式来重命名注入对象

(3) 如果限定不能删除 @Autowired ,那就可以再加上使用 @Qualifier,来删选 bean 对象

 

 解决方法

(1) 精确的描述 bean 的名称 (将注入的名称写对)

  1. package com.beans;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.beans.factory.annotation.Qualifier;
  4. import org.springframework.stereotype.Controller;
  5. @Controller
  6. public class UserController {
  7. @Autowired //[属性注入/字段注入]
  8. private User user2;
  9. public void sayHi() {
  10. System.out.println("User -> " + user2);
  11. }
  12. }
  1. import com.beans.*;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class app {
  5. public static void main(String[] args) {
  6. //1. 先得到上下文对象
  7. ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  8. UserController controller = context.getBean(UserController.class);
  9. controller.sayHi();
  10. }
  11. }
  1. package com.beans;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. public class UserBeans {
  6. @Bean(name = "userinfo") //[只使用一个 @Bean 是无法将对象存储到容器中]
  7. public User user1() {
  8. User user = new User();
  9. user.setId(1);
  10. user.setName("张三");
  11. return user;
  12. }
  13. @Bean
  14. public User user2() {
  15. User user = new User();
  16. user.setId(2);
  17. user.setName("李四");
  18. return user;
  19. }
  20. }

(2) 使用 @Resource 设置 name 的方式来重命名注入对象

(3) 如果限定不能删除 @Autowired ,那就可以再加上使用 @Qualifier,来删选 bean 对象

 


网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发