Sping对象的存储和读取
创始人
2025-05-29 06:41:38
0

文章目录

  • 一、更简单的存储对象到Sping的实现步骤
    • 1.先创建一个Maven
    • 2. 添加Spring Maven核心包
    • 3.配置Spring xml 文件 ->配置Spring组件扫描路径(所有需要存储在Spring中的对象都需要放在此目录)
    • 4. 创建一个普通类,添加Main(作用:方便后面演示)
    • 5. 使用注解实现对象存储在Spring框架(类注解/方法注解)
      • @Controller 控制器 (对象存储)
      • @Service 业务逻辑类
      • @Repository[数据持久层](DAO)
      • @Component[组件类]
      • @Configuration[配置类]
      • @Bean
    • 6.使用方法注解 @Bean 将对象存储到 Spring
    • 7.@Bean起别名
    • 8.注解之间的关系
    • 9.Spring是如何生成出类注解 beanName的?
  • 二、更简单的从Spring获取对象(@Autowired )
    • 1. 属性注入
    • 2. Setter注入
    • 3. 构造方法注入
    • 三种注入方式的区别
  • 另外一种从Spring获取对象注解(@Resource )
    • 1.属性注入
    • 2. Setter注入
  • @Autowired 和 @Resource 关于注入对象名称的问题
      • @Autowired 和 @Resource 有什么区别?


一、更简单的存储对象到Sping的实现步骤

1.先创建一个Maven

在这里插入图片描述

2. 添加Spring Maven核心包

pom.xml中添加Spring的上下文和管理对象模块

org.springframeworkspring-context5.2.3.RELEASEorg.springframeworkspring-beans5.2.3.RELEASE

3.配置Spring xml 文件 ->配置Spring组件扫描路径(所有需要存储在Spring中的对象都需要放在此目录)

在resource目录下新建一个xml文件,并配置Spring组件的扫描路径

在这里插入图片描述
也就是说,只有在com.demo下的类才有可能被存储到Spring当中




4. 创建一个普通类,添加Main(作用:方便后面演示)

5. 使用注解实现对象存储在Spring框架(类注解/方法注解)

1.类注解:@Controller[控制器]、@Service[业务逻辑类]、@Repository[数据持久类]、@Component[组件类]、@Configuration[配置类]
2.方法注解:@Bean
在这里插入图片描述

@Controller 控制器 (对象存储)

@Controller // 将当前的类存储到 Spring 中
public class UserController {/*** 对象中的测试方法* @param name*/public void testHello(String name) {System.out.println("hello Controller " + name);}
}

注意事项:

  1. 读取存入对象的id:默认情况下就是首字母小写

在这里插入图片描述

  1. 所有需要存储到 Spring框架中的对象的目录,必须在Spring 配置的目录下,conmponent-scan

在这里插入图片描述

@Service 业务逻辑类

@Service //将当前对象存储到 Spring 当中
public class UserService {public void printService(String name) {System.out.println("hello Service "+name);}
}

@Repository[数据持久层](DAO)

@Repository // 将对象存储到 Spring中
public class UserRepository {public void printRepository(String name) {System.out.println("hello repository "+name);}
}

@Component[组件类]

@Component //将对象存储到Spring中
public class UserComponent {public void printComponent(String name) {System.out.println("hello component "+name);}
}

@Configuration[配置类]

@Configuration // 将对象存储到Spring中
public class UserConfiguration {public void printConfiguration(String name) {System.out.println("hello Configuration "+name);}
}

@Bean

@Bean方法注解,可以把方法返回的对象注入到Spring中

public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//  得到 controller 对象UserController controller = applicationContext.getBean("userController",UserController.class);controller.printController("控制器");// 得到 service 对象UserService service = applicationContext.getBean("userService",UserService.class);service.printService("业务逻辑");// 得到 repository对象UserRepository repository = applicationContext.getBean("userRepository",UserRepository.class);repository.printRepository("数据持久DAO");// 得到 configurationUserConfiguration configuration = applicationContext.getBean("userConfiguration",UserConfiguration.class);configuration.printConfiguration("配置类");// 得到 componentUserComponent component = applicationContext.getBean("userComponent",UserComponent.class);component.printComponent("组件类");}

6.使用方法注解 @Bean 将对象存储到 Spring

注意事项:Spring 默认情况下是类扫描,因此如果使用的是方法注解 @Bean,那么必须要配合类注解(@Component)一起使用(也可以是其它注解),才能将方法返回对象顺利存储到 Spring中

@Component
public class UserBean {@Beanpublic User user() {//伪代码//查询数据库获取对象User user = new User();user.setId(1);user.setName("张三");user.setAge(20);return user;}
}

获取对象

public class App {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//通过 @Bean注解获取对象User user = applicationContext.getBean("user",User.class);System.out.println(user);}
}

7.@Bean起别名

注意:如果给@Bean起别名后,就只能用别名来获取对象了

@Component
public class UserBean {@Bean(name = {"getUser"})public User user() {//伪代码//查询数据库获取对象User user = new User();user.setId(1);user.setName("张三");user.setAge(20);return user;}
}

获取对象

public class App {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//通过 @Bean注解获取对象User user = applicationContext.getBean("getUser",User.class);System.out.println(user);}
}

@Bean还可以起多个别名

@Component
public class UserBean {@Bean(name = {"getUser","myUser"})public User user() {//伪代码//查询数据库获取对象User user = new User();user.setId(1);user.setName("张三");user.setAge(20);return user;}}

并且 nume = 可以省略

@Bean({"getUser","myUser"})public User user() {//伪代码//查询数据库获取对象User user = new User();user.setId(1);user.setName("张三");user.setAge(20);return user;}

8.注解之间的关系

为啥要有那么多注解,就是让程序员看到类注解之后,就能直接了解当前类的⽤途

通过源码可以发现,@controller/@Service/@Repository/@Configuration
这四个注解从业务逻辑来说,可以认为这四个注解是 @Component的子类

在这里插入图片描述

9.Spring是如何生成出类注解 beanName的?

查看 AnnotationBeanNameGenerator 中的源码
AnnotationBeanNameGenerator -> buildDefaultBeanName -> Introspector.decapitalize(shortClassName)

如果类名的长度大于1,并且第一个和第二个字母都是大写就直接返回
否则就把类名的第一个字母改为小写直接返回

在这里插入图片描述

二、更简单的从Spring获取对象(@Autowired )

从Spring中获取对象的手段:

  1. 属性注入(属性注册)UserController ——> UserService
  2. Setter 注入
  3. 构造方法注入
@Service //将当前对象存储到 Spring 当中
public class UserService {/*** 通过用户Id查询用户* @param id* @return*/public User findUserById(int id) {// 伪查询,不连接sqlUser user = new User();if (id == 1) {user.setId(1);user.setName("张三");user.setAge(18);} else {user.setId(2);user.setName("李四");user.setAge(20);}return user;}
}

1. 属性注入

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

@Controller // 将当前的类存储到 Spring 中
public class UserController {// 属性注入(属性注册), 从Spring中取出对象,注入到当前类中@Autowiredprivate UserService userService;public User findUserById(Integer id) {if (id == null) {// 如果是无效参数return new User();}return userService.findUserById(id);}
}

2. Setter注入

注意:必须在 Setter方法上加上 @Autowired 注解,不然会注入失败。又因为spring是类扫描的,所以要在当前类上加上对应注解,该对象才有可能存入 spring 中

@Controller
public class UserController2 {private UserService userService;public User findUserById(Integer id) {if (id == null) {return new User();}return userService.findUserById(id);}// Setter注入@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}
}

3. 构造方法注入

注意:如果类中只有一个构造方法,@Autowired注解可以省略

@Controller
public class UserController3 {private UserService userService;//通过构造方法注入,若果只是存在一个构造方法,那么@Autowired可以省略@Autowiredpublic UserController3(UserService userService) {this.userService = userService;}public UserController3(String name) {System.out.println(name);}public User findUserById(Integer id) {if (id == null) {//判断id合法return new User();}return userService.findUserById(id);}
}

三种方式的getBean实现

public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");// 方法1: 属性注入UserController userController = (UserController) context.getBean("userController");System.out.println(userController.findUserById(2));// 方法2: Setter注入UserController2 userController2 = context.getBean("userController2",UserController2.class);System.out.println(userController2.findUserById(1));// 方法3: 构造方法注入UserController3 userController3 = context.getBean("userController3",UserController3.class);System.out.println(userController3.findUserById(2));}

三种注入方式的区别

  • 属性注入的优点,使用方便;缺点是只能用于 Ioc容器,如果不是IoC容器就无法使用,并且只有在使用的时候才会出现 空指针异常
  • 构造方法注入是 Spring官方推荐的注入方式,它的缺点是如果有多个注入会显得比较臃肿,但出现这种情况你应该考虑一下当前类是否符合程序的单一职责的设计模式了,它的优点是通用性,在使用之前一定能保证注入的类不为空
  • Setter方式是Spring前期版本推荐的注入方式,但通用性不如构造方法,所以Spring先版本已经推荐使用构造方法注入的范式来进行类注入了

另外一种从Spring获取对象注解(@Resource )

@Resource 和 @Autowired 注解的使用方式非常类似

1.属性注入

@Controller
public class UserController4 {@Resourceprivate UserService userService;public User findUserById(Integer id) {if (id == null) {return new User();}return userService.findUserById(id);}
}

2. Setter注入

@Controller
public class UserController5 {private UserService userService;public User findUserById(Integer id) {if (id == null) {return new User();}return userService.findUserById(id);}@Resourcepublic void setUserService(UserService userService) {this.userService = userService;}
}

注意:@Resource不能通过构造方法注入对象

在这里插入图片描述

@Autowired 和 @Resource 关于注入对象名称的问题

@Autowired 和 @Resource 它们都是做了两手准备,它们会先从 一种类型进行选择,比如先从名称(ByName)进行获取Bean对象,如果根据名称获取不到,此时根据另一种类型(ByType)获取(根据名称或者类型获取

如果Bean对象只有一个的时候,注入对象名就无所谓了

在这里插入图片描述

问题来了:如果注入的名称是不存在的,并且类型有多个,那么注入就会失败

@Component
public class UserBean {@Beanpublic User getUser1() {User user = new User();user.setId(1);user.setName("张三");user.setAge(22);return user;}@Beanpublic User getUser2() {User user = new User();user.setId(2);user.setName("李四");user.setAge(20);return user;}
}

注入代码

@Service
public class UserService {@Resourceprivate User user;public User findUserById(int id) {User user = new User();if (id == 1) {user.setId(1);user.setName("张三");user.setAge(18);} else {user.setId(2);user.setName("李四");user.setAge(20);}return user;}
}

运行就会报错,因为这里名字不存在,并且有多个类型注入

同⼀类型多个 Bean 报错处理,可以为Bean重命名,再通过重命名的名字注入Bean对象

  1. 使用 @Resource(name=“指定bean名称”)
    加上 name 说明加载的时候是用 beanName加载的
@Service
public class UserService {@Resource(name = "getUser1")private User user;public User findUserById(int id) {User user = new User();if (id == 1) {user.setId(1);user.setName("张三");user.setAge(18);} else {user.setId(2);user.setName("李四");user.setAge(20);}return user;}
}

在这里插入图片描述
2.使用注入注解配合@Qualifier来进行解决

@Service
public class UserService {@Autowired@Qualifier(value = "getUser2")private User user;public User findUserById(int id) {User user = new User();if (id == 1) {user.setId(1);user.setName("张三");user.setAge(18);} else {user.setId(2);user.setName("李四");user.setAge(20);}return user;}
}

在这里插入图片描述

@Autowired 和 @Resource 有什么区别?

  1. 出身不同,@Autowired 来自于 Spring 框架,而 @Resource来自于 JDK
  2. 作用于不同,使用@Autowired可以进行 属性注入、Setter注入、构造器注入;而 @Resource只能进行 属性注入和Setter注入。
  3. 功能不同,@Resource可以配合更多属性进行使用,而 @Autowired 支持的属性较少,比如 @Resource 可以 配合 name 属性进行使用,从而完成对象的别名注入

上一篇:MySQL学习笔记(总结)

下一篇:JUC(十)

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...