Sping对象的存储和读取
创始人
2025-05-29 06:09:47
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 属性进行使用,从而完成对象的别名注入

相关内容

热门资讯

FIBA期待杨瀚森表现 最新实... 北京时间6月25日消息,FIBA国际篮联公布了最新一期世界杯预选赛亚太区球队实力榜,中国男篮排在澳大...
收评:创业板指放量反弹涨2.8... 市场冲高回落后,再度震荡拉升。黄白线分化明显,权重股走势较强。量能明显放大,沪深两市成交额3.59万...
巨头财报引爆A股存储芯片板块,... 当地时间6月24日美股盘后, 美光科技(MU.US)公布截至5月31日的2026财年第三财季财报,业...
银行、消金公司助贷余额增速不得... 近日,中国证券报记者从多位业内人士处独家获悉,5月以来,多地金融监管部门对部分中小银行、消金公司下达...
朱鸿接任陈航,担任钉钉科技有限... 消费日报-今朝新闻讯 天眼查显示,6月23日,钉钉科技有限公司发生工商变更,陈航卸任法定代表人、董事...
3日累跌超20%,德创环保:公... 6月25日, 德创环保(603177.SH)公告,公司股票于2026年6月23日、6月24日和6月2...
北京发布2026年第七轮拟供商... 央广网北京6月25日消息(记者门庭婷)6月25日,北京市规划和自然资源委员会网站发布了2026年第七...
开放麦 | 启明创投胡奇:从A... “2026年,创投圈的浪潮再次翻涌:AI从技术概念走进产业深水区,硬科技创业从“小众赛道” 变成“主...
腾讯孙忠怀:在行业转身处 6月24日,2026腾讯视频年度发布在上海举行。腾讯公司副总裁、腾讯在线视频董事长孙忠怀以《在行业转...
加息,突变!美联储,重磅传来!... 美联储政策路径突生变数。 美国商务部经济分析局最新公布的数据显示,5月个人消费支出(PCE)物价指数...
6月合肥上门收金必看!5步避坑... 2026年6月,合肥黄金市场持续高位运行,不少市民翻出家里闲置的旧金饰、投资金条想变现,上门回收因为...
潮汕女富豪挂帅后加码液冷!祥鑫... 潮汕女强人,带着百亿公司加码液冷散热。 6月24日晚间,祥鑫科技(002965.SZ)公告称,公司董...
马斯克向太空要电,GobiX ... 一场关于「去哪里找电」的全球竞赛,正在朝两个方向展开。 作者|周永亮 编辑| 郑玄 「太空光伏是不是...
原料药行业陷入周期低谷 有药企... 每经记者|许立波 每经编辑|魏文艺 “过完年到现在,我们整个团队每个月都在出差,跑遍了亚非拉、欧美市...
家门口筛查白内障!永顺泽家镇暖... 大众卫生报·新湖南客户端6月25日讯(通讯员 彭雪姣)为切实解决辖区老年性白内障患者异地就医奔波、就...
终于等到!油价马上再大跌,这个... 点击添加图片描述(最多60个字) 编辑 各位车主朋友,好消息接二连三! 继6月18日油价大幅下调...
丈量出海新路 世界酒庄影响力指... 长期以来,全球酒庄评价体系由西方机构主导,且大多局限于单一酒种、单一评价维度,这一局面正逐渐被打破。...
峰瑞资本创始合伙人李丰:从资本... “2026年,创投圈的浪潮再次翻涌:AI从技术概念走进产业深水区,硬科技创业从“小众赛道” 变成“主...
原创 A... 迈向成熟,还有茁壮成长的机会。 作者 | 方璐 编辑丨于婞 来源 | 野马财经 2026年6月21日...
为企业解锁出海新通道!亚太中小... 6月24日下午,作为2026年APEC中小企业工商论坛的重要组成部分,亚太中小企业国际化合作发展论坛...