关于 Spring 的创建及简单的使用
可以参考这篇文章
之前的存储方式是利用
进行存储
但这种方式存在一个弊端
即需要存储的 Bean 过多时, 手动添加过于繁琐
利用注解可以有效规避这种情况
添加如下代码至xml
文件中
<content:component-scan base-package="">content:component-scan>
base-package=""
引号中填写的是扫描路径
完整代码
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
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">
<content:component-scan base-package="">content:component-scan>
beans>
如图
base-package="com.demo"
扫描路径为com
包下的demo
包下的全部
所有的类都写在 Java 根路径下, 没有目录, 该如何存储 / 获取 Bean
(了解即可, 通常不会这么做)
base-package="**"
将扫描路径更改为根目录下的全部
*
表示根目录
**
表示根目录下的全部
在 Spring Core 中, 类注解之间的区别不大
添加 @Controller 注解存储 Bean
获取 Bean
添加 @Service 注解存储 Bean
获取 Bean
添加 @Repository 注解存储 Bean
获取 Bean
添加 @Component 注解存储 Bean
获取 Bean
添加 @Configuration 注解存储 Bean
获取 Bean
通过添加注解的方式存储 Bean, 获取 Bean 时的 Id 该如何命名
UserInfo
, 其对应的Id
为userInfo
)userInfo
, 其对应的Id
为userInfo
)UInfo
, 其对应的Id
为UInfo
)源码分析
找到AnnotationBeanNameGenerator
的generateBeanName()
点击buildDefaultBeanName()
点击buildDefaultBeanName()
点击decapitalize()
找到最终的调用方法
分析这段代码
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))){ return name; }
如果长度 > 1 且第 1 个字符与第 0 个字符均是大写, 返回该字符串
(当类名的首字母和第二个字母均为大写, 不做改变)
chars[0] = Character.toLowerCase(chars[0]);
将第 0 个字符变为小写
(当类名为标准驼峰命名时, 将类名的首字母小写, 其余字母不变)
(当类名的首字母为小写时, 不做改变)
既然都可以通过添加类注解的方式存储 Bean
那为何还需要五个类注解呢?
举个栗子
通过车牌可以了解是哪里的车, 例如 京 → 北京, 津 → 天津
(通过类注解可以了解当前类的用途)
类注解的用途
举个栗子
滑稽老哥家中失窃, 选择报警
接警员判断情况是否属实, 避免小孩子的恶作剧
(@Controller)
警局根据接警员的信息派出一些警察负责跟进
(@Service)
出警的警察负责这一起案件
(@Repository)
@Component 是 @Controller, @Service, @Repository, @Configuration 的父类
方法注解需搭配类注解一同使用
(目的是为了提高效率)
新建一个 Student 类
新建一个 StudentBeans 类
为 getStu() 添加方法注解(@Bean)
为 StudentBeans 添加类注解(@Component)
@Bean(name = {"s1", "s2"})
)默认情况下 getBean() 对应的 Id 为方法名
@Bean 后可以跟 name
从 Spring 中获取 Bean 也称为对象装配, 对象注入
对象装配(对象注入)的方式可以划分为 3 种
属性注入的效果等同于赋值
举个栗子
@Autowired
private StudentService studentService;
private int num = 10;
StudentService studentService
利用属性注入, 由 Spring 框架赋值
int num
未利用属性注入, 由程序员赋值
综上, 再次说明了 Spring 是一个包含众多工具方法的 IOC 容器
(IOC → 控制反转)
属性注入的优点
属性注入的缺点
不能注入不可变对象(final 修饰)
final 修饰的对象有 2 种赋值方式
只适用于 IOC 容器
@Autowired 来自于 Spring
Spring 是一个包含众多工具方法的 IOC 容器
因此只适用于 IOC 容器
更容易违背单一设计原则
属性注入的方式实现简单
因此也更容易将其他无关的对象一并注入
也就更容易违背单一设计原则
Set 注入的优点
Set 注入的缺点
更符合单一设计原则
Set 注入的实现方式相比于属性注入较复杂
因此相较于属性注入也就避免了将其他无关的对象一并注入的情况
(更符合单一设计原则)
不能注入不可变对象(final 修饰)
final 修饰的对象有 2 种赋值方式
注入的对象可被修改
Set 注入相较于属性注入更危险!
属性注入的对象也可被修改
但 Set 注入除通过属性注入的方式修改注入的对象
也可通过 set() 方法修改注入的对象
set() 方法既可以被 Spring 调用
也可以被其他对象调用
注意
构造方法注入的优点
构造方法注入的缺点
使用 @Resource 实现属性注入
使用 @Resource 实现 Set 注入
使用 @Resource 不能实现构造方法注入
来源不同
@Resource
@Autowired
支持参数不同
@Resource
@Autowired
存在返回同一个类型的多个方法时
利用@Resource(name = "")
可以将其进行区分
@Autowired 无法设置 name
只能填写对应的对象
如果想写成 student 形式
需搭配@Qualifier()
进行使用, 括号中填写的内容为对应的对象
创作不易,如果对您有帮助,希望您能点个免费的赞
大家有什么不太理解的,可以私信或者评论区留言,一起加油